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

```bash
# 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.

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

```bash
/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:
   ```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 <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`**

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