Files
natsnet/docs/plans/2026-02-27-batch-2-parser-sublist-memstore-remainders-plan.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

16 KiB

Batch 2 (Parser, Sublist, MemStore remainders) Implementation Plan

For Codex: REQUIRED SUB-SKILL: Use executeplan to implement this plan task-by-task.

Goal: Implement and verify all 8 Batch 2 features with Go-parity behavior and evidence-backed status promotion to verified.

Architecture: Execute Batch 2 in three feature groups (parser, sublist, memstore). For each feature, run a strict verify-first loop: read Go source, implement/adjust minimal C# parity, run focused tests, then pass group build/test gates before any status updates. Use additive compatibility methods only if mapping alignment requires them.

Tech Stack: .NET 10, C# latest, xUnit 3, Shouldly, NSubstitute, PortTracker CLI, SQLite (porting.db)

Design doc: docs/plans/2026-02-27-batch-2-parser-sublist-memstore-remainders-design.md


Batch 2 Working Set

Feature groups (max group size <= 20 features):

  • Group A (3 features): 2588, 2590, 2591
  • Group B (3 features): 3446, 3447, 3448
  • Group C (2 features): 2068, 2086

Batch facts:

  • Total features: 8
  • Total tracked tests in batch: 0
  • Required dependency: Batch 1
  • Related Go files: server/parser.go, server/sublist.go, server/memstore.go

If dotnet is not on PATH, use /usr/local/share/dotnet/dotnet for all commands in this plan.


MANDATORY VERIFICATION PROTOCOL

NON-NEGOTIABLE: Every feature in this batch must pass this protocol before status advancement.

What Counts as Real Feature Verification

A feature is eligible for verified only when all are true:

  1. Mapped behavior is confirmed against the referenced Go implementation.
  2. .NET implementation exists and executes without placeholder logic.
  3. Related tests execute (non-zero discovered) and pass.
  4. Group build gate is green after the feature changes.
  5. Stub scans on touched files are clean for new/edited code.

Per-Feature Verification Loop (REQUIRED for every feature ID)

  1. Read Go source for the feature (feature show <id> then open referenced lines in Go file).
  2. Implement or adjust C# in mapped target files.
  3. Run a focused build and tests for that feature area.
  4. Confirm test discovery is non-zero and failures are zero.
  5. Add feature ID to the group verification evidence list only after green results.

Template loop command set:

# Inspect mapping
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- feature show <id> --db porting.db

# Build check after feature change
/usr/local/share/dotnet/dotnet build dotnet/

# Run focused related tests
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
  --filter "FullyQualifiedName~<RelatedTestClass>" --verbosity normal

Stub Detection Check (REQUIRED after each feature group)

Run on changed source + test files before status updates.

# 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)

/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):

/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):

/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):

/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):

/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
  feature batch-update --ids "<ids>" --set-status stub --db porting.db --execute

/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
  feature batch-update --ids "<ids>" --set-status complete --db porting.db --execute

/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
  feature batch-update --ids "<ids>" --set-status verified --db porting.db --execute

If audit rejects an evidence-backed promotion:

/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
  feature update <id> --status verified --db porting.db --override "manual verification evidence: <reason>"

Checkpoint Protocol Between Tasks (REQUIRED)

After completing each task group (A, B, C), before starting the next:

  1. Full build:
    /usr/local/share/dotnet/dotnet build dotnet/
    
  2. Full unit test run:
    /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:

/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
  feature update <id> --status deferred --db porting.db --override "blocked: <specific missing dependency/runtime precondition>"

Task 1: Group A - Parser Remainders (2588, 2590, 2591)

Files:

  • Modify: dotnet/src/ZB.MOM.NatsNet.Server/Protocol/ProtocolParser.cs
  • Modify (only if mapping wrapper needed): dotnet/src/ZB.MOM.NatsNet.Server/ClientConnection.cs
  • Modify/Test: dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Protocol/ProtocolParserTests.cs

Step 1: Mark parser feature IDs as stub

/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

/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

/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

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

/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

/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

/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

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

/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

/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

/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

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

/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- batch show 2 --db porting.db

Step 2: Complete the batch

/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- batch complete 2 --db porting.db

Step 3: Validate global summary and dependency readiness

/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

./reports/generate-report.sh

Step 5: Final commit

git add porting.db reports/
git commit -m "chore(batch2): complete parser-sublist-memstore remainder batch"