diff --git a/docs/batches.md b/docs/batches.md index a21f28f..bb770c1 100644 --- a/docs/batches.md +++ b/docs/batches.md @@ -14,15 +14,15 @@ | Batch # | Batch Name | Design File | Plan File | Status | |---------|------------|-------------|-----------|--------| -| 0 | Implementable Tests | | | not_planned | -| 1 | Proto, Const, CipherSuites, NKey, JWT | | | not_planned | -| 2 | Parser, Sublist, MemStore remainders | | | not_planned | -| 3 | SendQ, Service, Client ProxyProto | | | not_planned | -| 4 | Logging | | | not_planned | -| 5 | JetStream Errors | | | not_planned | +| 0 | Implementable Tests | [design](plans/2026-02-27-batch-0-implementable-tests-design.md) | [plan](plans/2026-02-27-batch-0-implementable-tests-plan.md) | planned | +| 1 | Proto, Const, CipherSuites, NKey, JWT | [design](plans/2026-02-27-batch-1-proto-const-ciphersuites-nkey-jwt-design.md) | [plan](plans/2026-02-27-batch-1-proto-const-ciphersuites-nkey-jwt-plan.md) | planned | +| 2 | Parser, Sublist, MemStore remainders | [design](plans/2026-02-27-batch-2-parser-sublist-memstore-remainders-design.md) | [plan](plans/2026-02-27-batch-2-parser-sublist-memstore-remainders-plan.md) | planned | +| 3 | SendQ, Service, Client ProxyProto | [design](plans/2026-02-27-batch-3-sendq-service-client-proxyproto-design.md) | [plan](plans/2026-02-27-batch-3-sendq-service-client-proxyproto-plan.md) | planned | +| 4 | Logging | [design](plans/2026-02-27-batch-4-logging-design.md) | [plan](plans/2026-02-27-batch-4-logging-plan.md) | planned | +| 5 | JetStream Errors | [design](plans/2026-02-27-batch-5-jetstream-errors-design.md) | [plan](plans/2026-02-27-batch-5-jetstream-errors-plan.md) | planned | | 6 | Opts package-level functions | | | not_planned | | 7 | Opts class methods + Reload | | | not_planned | -| 8 | Store Interfaces | | | not_planned | +| 8 | Store Interfaces | [design](plans/2026-02-27-batch-8-store-interfaces-design.md) | [plan](plans/2026-02-27-batch-8-store-interfaces-plan.md) | planned | | 9 | Auth, DirStore, OCSP foundations | | | not_planned | | 10 | OCSP Cache + JS Events | | | not_planned | | 11 | FileStore Init | | | not_planned | diff --git a/docs/plans/2026-02-27-batch-1-proto-const-ciphersuites-nkey-jwt-design.md b/docs/plans/2026-02-27-batch-1-proto-const-ciphersuites-nkey-jwt-design.md new file mode 100644 index 0000000..08f7661 --- /dev/null +++ b/docs/plans/2026-02-27-batch-1-proto-const-ciphersuites-nkey-jwt-design.md @@ -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)` 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. diff --git a/docs/plans/2026-02-27-batch-1-proto-const-ciphersuites-nkey-jwt-plan.md b/docs/plans/2026-02-27-batch-1-proto-const-ciphersuites-nkey-jwt-plan.md new file mode 100644 index 0000000..1a3d5b8 --- /dev/null +++ b/docs/plans/2026-02-27-batch-1-proto-const-ciphersuites-nkey-jwt-plan.md @@ -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~." --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~" --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 "" --set-status complete --db porting.db --execute + +dotnet run --project tools/NatsNet.PortTracker -- \ + feature batch-update --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 --status verified --db porting.db --override "manual verification evidence: " +``` + +### 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 --status deferred --db porting.db --override "blocked: " +``` + +--- + +### 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)` 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" +``` diff --git a/docs/plans/2026-02-27-batch-2-parser-sublist-memstore-remainders-design.md b/docs/plans/2026-02-27-batch-2-parser-sublist-memstore-remainders-design.md new file mode 100644 index 0000000..7e46d69 --- /dev/null +++ b/docs/plans/2026-02-27-batch-2-parser-sublist-memstore-remainders-design.md @@ -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 ` + 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. diff --git a/docs/plans/2026-02-27-batch-2-parser-sublist-memstore-remainders-plan.md b/docs/plans/2026-02-27-batch-2-parser-sublist-memstore-remainders-plan.md new file mode 100644 index 0000000..4d45cd5 --- /dev/null +++ b/docs/plans/2026-02-27-batch-2-parser-sublist-memstore-remainders-plan.md @@ -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 ` 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 --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~" --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 "" --set-status stub --db porting.db --execute + +/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \ + feature batch-update --ids "" --set-status complete --db porting.db --execute + +/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \ + feature batch-update --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 --status verified --db porting.db --override "manual verification evidence: " +``` + +### 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 --status deferred --db porting.db --override "blocked: " +``` + +--- + +### 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" +``` diff --git a/docs/plans/2026-02-27-batch-3-sendq-service-client-proxyproto-design.md b/docs/plans/2026-02-27-batch-3-sendq-service-client-proxyproto-design.md new file mode 100644 index 0000000..0ab3abc --- /dev/null +++ b/docs/plans/2026-02-27-batch-3-sendq-service-client-proxyproto-design.md @@ -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` 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. diff --git a/docs/plans/2026-02-27-batch-3-sendq-service-client-proxyproto-plan.md b/docs/plans/2026-02-27-batch-3-sendq-service-client-proxyproto-plan.md new file mode 100644 index 0000000..8a9be4d --- /dev/null +++ b/docs/plans/2026-02-27-batch-3-sendq-service-client-proxyproto-plan.md @@ -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 --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 --status deferred --db porting.db --override "blocked: " + +/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \ + feature update --status n_a --db porting.db --override "n/a: " +``` + +### 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` + 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" +``` diff --git a/docs/plans/2026-02-27-batch-4-logging-design.md b/docs/plans/2026-02-27-batch-4-logging-design.md new file mode 100644 index 0000000..068090f --- /dev/null +++ b/docs/plans/2026-02-27-batch-4-logging-design.md @@ -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. diff --git a/docs/plans/2026-02-27-batch-4-logging-plan.md b/docs/plans/2026-02-27-batch-4-logging-plan.md new file mode 100644 index 0000000..f19b2eb --- /dev/null +++ b/docs/plans/2026-02-27-batch-4-logging-plan.md @@ -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 --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 --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~" --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 "" --set-status stub --db porting.db --execute + +/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \ + feature batch-update --ids "" --set-status complete --db porting.db --execute + +/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \ + feature batch-update --ids "" --set-status verified --db porting.db --execute + +/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \ + test batch-update --ids "" --set-status stub --db porting.db --execute + +/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \ + test batch-update --ids "" --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 --status --db porting.db --override "verification evidence: " +``` + +### 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 --status deferred --db porting.db \ + --override "blocked: " + + /usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \ + test update --status deferred --db porting.db \ + --override "blocked: " + ``` +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? diff --git a/docs/plans/2026-02-27-batch-5-jetstream-errors-design.md b/docs/plans/2026-02-27-batch-5-jetstream-errors-design.md new file mode 100644 index 0000000..696023d --- /dev/null +++ b/docs/plans/2026-02-27-batch-5-jetstream-errors-design.md @@ -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. diff --git a/docs/plans/2026-02-27-batch-5-jetstream-errors-plan.md b/docs/plans/2026-02-27-batch-5-jetstream-errors-plan.md new file mode 100644 index 0000000..ff7ee3f --- /dev/null +++ b/docs/plans/2026-02-27-batch-5-jetstream-errors-plan.md @@ -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 ` + 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" \ + --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 "" --set-status stub --db porting.db --execute + +dotnet run --project tools/NatsNet.PortTracker -- \ + feature batch-update --ids "" --set-status complete --db porting.db --execute + +dotnet run --project tools/NatsNet.PortTracker -- \ + feature batch-update --ids "" --set-status verified --db porting.db --execute + +dotnet run --project tools/NatsNet.PortTracker -- \ + test batch-update --ids "" --set-status verified --db porting.db --execute +``` + +If audit disagrees, use explicit reason: + +```bash +dotnet run --project tools/NatsNet.PortTracker -- \ + feature update --status verified --db porting.db \ + --override "manual verification evidence: " +``` + +### 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 --status deferred --db porting.db \ + --override "blocked: " + +dotnet run --project tools/NatsNet.PortTracker -- \ + test update --status deferred --db porting.db \ + --override "blocked: " +``` + +--- + +### 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 ` + 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~." --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 --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" +``` diff --git a/docs/plans/2026-02-27-batch-8-store-interfaces-design.md b/docs/plans/2026-02-27-batch-8-store-interfaces-design.md new file mode 100644 index 0000000..3028b1f --- /dev/null +++ b/docs/plans/2026-02-27-batch-8-store-interfaces-design.md @@ -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. diff --git a/docs/plans/2026-02-27-batch-8-store-interfaces-plan.md b/docs/plans/2026-02-27-batch-8-store-interfaces-plan.md new file mode 100644 index 0000000..4548215 --- /dev/null +++ b/docs/plans/2026-02-27-batch-8-store-interfaces-plan.md @@ -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 --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 "" --set-status stub --db porting.db --execute + +dotnet run --project tools/NatsNet.PortTracker -- \ + feature batch-update --ids "" --set-status complete --db porting.db --execute + +dotnet run --project tools/NatsNet.PortTracker -- \ + feature batch-update --ids "" --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 --status verified --db porting.db \ + --override "manual verification evidence: " +``` + +### 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 porting.db + git commit -m "feat(batch8): " + ``` + +--- + +## 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 --status deferred --db porting.db \ + --override "blocked: " + +dotnet run --project tools/NatsNet.PortTracker -- \ + test update 1751 --status deferred --db porting.db \ + --override "blocked: " +``` + +--- + +### 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 " +``` + +**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? diff --git a/reports/current.md b/reports/current.md index a89c003..16fb265 100644 --- a/reports/current.md +++ b/reports/current.md @@ -1,6 +1,6 @@ # NATS .NET Porting Status Report -Generated: 2026-02-27 18:23:18 UTC +Generated: 2026-02-27 19:11:30 UTC ## Modules (12 total) diff --git a/reports/report_f98e334.md b/reports/report_f98e334.md new file mode 100644 index 0000000..16fb265 --- /dev/null +++ b/reports/report_f98e334.md @@ -0,0 +1,37 @@ +# NATS .NET Porting Status Report + +Generated: 2026-02-27 19:11:30 UTC + +## Modules (12 total) + +| Status | Count | +|--------|-------| +| verified | 12 | + +## Features (3673 total) + +| Status | Count | +|--------|-------| +| deferred | 2377 | +| n_a | 24 | +| stub | 1 | +| verified | 1271 | + +## Unit Tests (3257 total) + +| Status | Count | +|--------|-------| +| deferred | 2640 | +| n_a | 187 | +| verified | 430 | + +## Library Mappings (36 total) + +| Status | Count | +|--------|-------| +| mapped | 36 | + + +## Overall Progress + +**1924/6942 items complete (27.7%)**