# 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" ```