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

5.3 KiB

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.

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.

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.