Files
natsnet/docs/plans/2026-02-27-batch-2-parser-sublist-memstore-remainders-design.md
Joseph Doherty b928be4f2f Add batch plans for batches 1-5 and 8 (rounds 1-3)
Generated design docs and implementation plans via Codex for:
- Batch 1: Proto, Const, CipherSuites, NKey, JWT
- Batch 2: Parser, Sublist, MemStore remainders
- Batch 3: SendQ, Service, Client ProxyProto
- Batch 4: Logging
- Batch 5: JetStream Errors
- Batch 8: Store Interfaces

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

128 lines
5.3 KiB
Markdown

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