# Batch 8 (Store Interfaces) Implementation Plan

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

**Goal:** Implement and verify Batch 8 store-interface parity from `server/store.go` (27 features + 1 tracked test) with evidence-backed status updates and zero stub work.

**Architecture:** Implement Batch 8 in two feature groups (12 + 15 IDs) centered on `StoreTypes.cs` parity helpers plus focused unit tests in `StoreTypesTests.cs`. Run strict per-feature verification loops and gate status promotions behind build/test/stub checks. Treat tracked test `#1751` separately: pass with a real behavior test or keep deferred with explicit blocker evidence.

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

**Design doc:** `docs/plans/2026-02-27-batch-8-store-interfaces-design.md`

---

I'm using `writeplan` to create the implementation plan.

## Batch 8 Working Set

Batch facts:

- Batch ID: `8`
- Features: `27` (currently `deferred`)
- Tests: `1` (currently `deferred`)
- Dependencies: none
- Go file: `server/store.go`

Feature groups (max ~20 features per group):

- **Group A (12):** `3164,3165,3166,3168,3171,3187,3188,3189,3191,3192,3193,3194`
- **Group B (15):** `3172,3173,3174,3175,3176,3177,3178,3179,3180,3181,3182,3183,3184,3185,3186`

Tracked test:

- **Test ID 1751:** `JetStreamEngineTests.JetStreamDirectGetUpToTime_ShouldSucceed`

Primary files:

- `dotnet/src/ZB.MOM.NatsNet.Server/JetStream/StoreTypes.cs`
- `dotnet/src/ZB.MOM.NatsNet.Server/JetStream/StoreParity.cs` (create only if needed for clarity)
- `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/JetStream/StoreTypesTests.cs` (new)
- `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/JetStreamEngineTests.Impltests.cs` (tracked test `1751`)
- `porting.db`

---

## MANDATORY VERIFICATION PROTOCOL

> **NON-NEGOTIABLE:** every feature/test status update in this batch must follow this protocol.

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

1. Read exact Go source mapping from tracker:
   ```bash
   dotnet run --project tools/NatsNet.PortTracker -- feature show <id> --db porting.db
   ```
2. Open mapped Go code (`server/store.go`) and confirm behavior at mapped line range.
3. Implement/update mapped C# method(s) in the mapped class/file.
4. Build immediately:
   ```bash
   dotnet build dotnet/
   ```
5. Run related tests for that feature slice:
   ```bash
   dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
     --filter "FullyQualifiedName~StoreTypesTests" --verbosity normal
   ```
6. Only if build+related tests are green, include the feature ID in status-promotion candidates.

### Stub Detection Check (REQUIRED after every feature group and test task)

Run these checks on all touched files before any status promotion:

```bash
grep -RInE "NotImplementedException|TODO|PLACEHOLDER" \
  dotnet/src/ZB.MOM.NatsNet.Server/JetStream/Store*.cs \
  dotnet/tests/ZB.MOM.NatsNet.Server.Tests/JetStream/StoreTypesTests.cs \
  dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/JetStreamEngineTests.Impltests.cs

grep -RInE "^\s*\{\s*\}$|Assert\.True\(true\)|Assert\.Pass\(" \
  dotnet/tests/ZB.MOM.NatsNet.Server.Tests/JetStream/StoreTypesTests.cs \
  dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/JetStreamEngineTests.Impltests.cs
```

Any match blocks status updates until resolved or explicitly deferred.

### Build Gate (REQUIRED after each feature group)

```bash
dotnet build dotnet/
```

Required: `0` build errors.

### Test Gate (REQUIRED before marking features `verified`)

All related tests must pass before features in that group can move to `verified`:

```bash
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
  --filter "FullyQualifiedName~StoreTypesTests|FullyQualifiedName~JetStreamMemoryStoreTests|FullyQualifiedName~StorageEngineTests" \
  --verbosity normal
```

For test-linked feature `3191`, `unit_test #1751` must also be resolved (pass or explicit deferred reason) before final batch closure.

### Status Update Protocol (REQUIRED)

Rules:

- Maximum `15` IDs per `feature batch-update` / `test batch-update` command.
- Evidence is mandatory for each update chunk:
  - latest build gate output
  - related test gate output
  - stub detection output
- Valid promotion path:
  - Features: `deferred -> stub -> complete -> verified`
  - Test `1751`: `deferred -> stub -> verified` (or remain `deferred` with reason)

Command templates:

```bash
dotnet run --project tools/NatsNet.PortTracker -- \
  feature batch-update --ids "<max15ids>" --set-status stub --db porting.db --execute

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

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

dotnet run --project tools/NatsNet.PortTracker -- \
  test update 1751 --status verified --db porting.db
```

If audit disagrees, include explicit justification:

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

### Checkpoint Protocol Between Tasks (REQUIRED)

After each task (Group A, Group B, Test 1751), before continuing:

1. Full build:
   ```bash
   dotnet build dotnet/
   ```
2. Full unit tests:
   ```bash
   dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --verbosity normal
   ```
3. Commit task slice:
   ```bash
   git add <touched-files> porting.db
   git commit -m "feat(batch8): <task-slice-summary>"
   ```

---

## ANTI-STUB GUARDRAILS

### Forbidden Patterns

Production code forbidden:

- `throw new NotImplementedException()`
- Empty public/internal method bodies used as placeholders
- `return default;` or `return null;` where Go logic requires real behavior
- unresolved `TODO`/`PLACEHOLDER` markers in touched Batch 8 code

Test code forbidden for `verified` status:

- `Assert.True(true)` / `Assert.Pass()`
- method-name/self-string assertions that do not exercise production code
- empty test bodies
- single trivial assert that does not validate mapped behavior

### Hard Limits

- Max `20` feature IDs per task group (Batch 8 uses groups of `12` and `15`)
- Max `15` IDs per status update command
- No `verified` feature status without passing related test gate
- No `verified` test status for skipped/non-behavioral tests
- One group per verification cycle (no cross-group bulk promotion)

### If You Get Stuck (Explicit Rule)

Do not stub and do not fake-pass.

1. Keep the blocked item as `deferred`.
2. Record concrete blocker in override reason.
3. Capture command output showing the blocker.
4. Continue with next unblocked item.

Example:

```bash
dotnet run --project tools/NatsNet.PortTracker -- \
  feature update <id> --status deferred --db porting.db \
  --override "blocked: <specific missing runtime/api/infrastructure dependency>"

dotnet run --project tools/NatsNet.PortTracker -- \
  test update 1751 --status deferred --db porting.db \
  --override "blocked: <specific missing runtime/api/infrastructure dependency>"
```

---

### Task 1: Baseline + Group A Implementation (12 features)

**Files:**

- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/JetStream/StoreTypes.cs`
- Create (if needed): `dotnet/src/ZB.MOM.NatsNet.Server/JetStream/StoreParity.cs`
- Create: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/JetStream/StoreTypesTests.cs`
- Modify: `porting.db`

Group A IDs:

- `3164,3165,3166,3168,3171,3187,3188,3189,3191,3192,3193,3194`

**Step 1: Mark Group A as `stub` (single chunk <=15)**

```bash
dotnet run --project tools/NatsNet.PortTracker -- \
  feature batch-update --ids "3164,3165,3166,3168,3171,3187,3188,3189,3191,3192,3193,3194" \
  --set-status stub --db porting.db --execute
```

**Step 2: Write failing Group A tests in `StoreTypesTests`**

Cover:

- encoded-stream header detection
- decode success/failure/corrupt paths
- delete-block state parity
- consumer-state encode shape checks
- out-of-space/cluster-reset predicates
- `StoreMsg.copy` behavior
- byte/string conversion + copy isolation + permission error predicate

**Step 3: Run Group A focused tests and confirm FAIL**

```bash
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
  --filter "FullyQualifiedName~StoreTypesTests" --verbosity normal
```

**Step 4: Implement Group A production code minimally to pass tests**

**Step 5: Re-run Group A focused tests and confirm PASS**

Same command as Step 3; require `Failed: 0`.

**Step 6: Run stub detection + build gate + test gate**

Use protocol commands above.

**Step 7: Promote Group A statuses to `complete` then `verified`**

```bash
dotnet run --project tools/NatsNet.PortTracker -- \
  feature batch-update --ids "3164,3165,3166,3168,3171,3187,3188,3189,3191,3192,3193,3194" \
  --set-status complete --db porting.db --execute

dotnet run --project tools/NatsNet.PortTracker -- \
  feature batch-update --ids "3164,3165,3166,3168,3171,3187,3188,3189,3191,3192,3193,3194" \
  --set-status verified --db porting.db --execute
```

**Step 8: Execute checkpoint protocol and commit**

```bash
git add dotnet/src/ZB.MOM.NatsNet.Server/JetStream/StoreTypes.cs \
        dotnet/src/ZB.MOM.NatsNet.Server/JetStream/StoreParity.cs \
        dotnet/tests/ZB.MOM.NatsNet.Server.Tests/JetStream/StoreTypesTests.cs \
        porting.db

git commit -m "feat(batch8): implement store codec/helpers parity group A"
```

---

### Task 2: Group B Enum String/JSON Parity (15 features)

**Files:**

- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/JetStream/StoreTypes.cs`
- Modify/Create: `dotnet/src/ZB.MOM.NatsNet.Server/JetStream/StoreParity.cs`
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/JetStream/StoreTypesTests.cs`
- Modify: `porting.db`

Group B IDs:

- `3172,3173,3174,3175,3176,3177,3178,3179,3180,3181,3182,3183,3184,3185,3186`

**Step 1: Mark Group B as `stub` (15 IDs = one chunk)**

```bash
dotnet run --project tools/NatsNet.PortTracker -- \
  feature batch-update --ids "3172,3173,3174,3175,3176,3177,3178,3179,3180,3181,3182,3183,3184,3185,3186" \
  --set-status stub --db porting.db --execute
```

**Step 2: Write failing enum parity tests**

Cover all mapped cases:

- `String()` parity text values
- marshal/unmarshal JSON token values
- invalid-value error behavior
- `DeliverPolicy` special `"undefined"` mapping behavior

**Step 3: Run focused tests and confirm FAIL**

```bash
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
  --filter "FullyQualifiedName~StoreTypesTests" --verbosity normal
```

**Step 4: Implement Group B enum string/JSON parity**

**Step 5: Re-run focused tests and confirm PASS**

Same command as Step 3; require `Failed: 0`.

**Step 6: Run stub detection + build gate + test gate**

Use protocol commands above.

**Step 7: Promote Group B statuses to `complete` then `verified`**

```bash
dotnet run --project tools/NatsNet.PortTracker -- \
  feature batch-update --ids "3172,3173,3174,3175,3176,3177,3178,3179,3180,3181,3182,3183,3184,3185,3186" \
  --set-status complete --db porting.db --execute

dotnet run --project tools/NatsNet.PortTracker -- \
  feature batch-update --ids "3172,3173,3174,3175,3176,3177,3178,3179,3180,3181,3182,3183,3184,3185,3186" \
  --set-status verified --db porting.db --execute
```

**Step 8: Execute checkpoint protocol and commit**

```bash
git add dotnet/src/ZB.MOM.NatsNet.Server/JetStream/StoreTypes.cs \
        dotnet/src/ZB.MOM.NatsNet.Server/JetStream/StoreParity.cs \
        dotnet/tests/ZB.MOM.NatsNet.Server.Tests/JetStream/StoreTypesTests.cs \
        porting.db

git commit -m "feat(batch8): implement store enum parity group B"
```

---

### Task 3: Tracked Test 1751 (`JetStreamDirectGetUpToTime_ShouldSucceed`)

**Files:**

- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/JetStreamEngineTests.Impltests.cs`
- Modify: `porting.db`

**Step 1: Mark test 1751 as `stub`**

```bash
dotnet run --project tools/NatsNet.PortTracker -- \
  test update 1751 --status stub --db porting.db
```

**Step 2: Port failing test logic from Go `TestJetStreamDirectGetUpToTime`**

- Preserve the behavior checks (distant past/future, before first, before fifth).
- Ensure it exercises real server/message paths, not constant/string-only assertions.

**Step 3: Run the single mapped test and confirm real execution**

```bash
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
  --filter "FullyQualifiedName~JetStreamEngineTests.JetStreamDirectGetUpToTime_ShouldSucceed" \
  --verbosity normal
```

Required: at least one executed test and `Failed: 0`.

**Step 4: If blocked by missing runtime infrastructure, defer with reason (do not stub)**

```bash
dotnet run --project tools/NatsNet.PortTracker -- \
  test update 1751 --status deferred --db porting.db \
  --override "blocked: requires <specific runtime/infra gap>"
```

**Step 5: If passing, promote test to `verified`**

```bash
dotnet run --project tools/NatsNet.PortTracker -- \
  test update 1751 --status verified --db porting.db
```

**Step 6: Run checkpoint protocol and commit**

```bash
git add dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/JetStreamEngineTests.Impltests.cs \
        porting.db

git commit -m "test(batch8): resolve jetstream direct get up-to-time mapping"
```

---

### Task 4: Batch 8 Final Closure

**Files:**

- Modify: `porting.db`
- Optional regenerate: `reports/current.md`

**Step 1: Re-run final evidence gates**

```bash
dotnet build dotnet/
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --verbosity normal
```

**Step 2: Confirm all Batch 8 IDs are closed correctly**

```bash
dotnet run --project tools/NatsNet.PortTracker -- batch show 8 --db porting.db
```

Required end-state:

- Features: `verified` (or explicit `deferred` only with blocker reason)
- Test `1751`: `verified` or explicit `deferred` with blocker reason

**Step 3: Complete batch if eligibility checks pass**

```bash
dotnet run --project tools/NatsNet.PortTracker -- batch complete 8 --db porting.db
```

**Step 4: Regenerate report and commit closure artifacts**

```bash
./reports/generate-report.sh

git add porting.db reports/current.md
git commit -m "chore(batch8): close store interfaces batch with verification evidence"
```

---

Plan complete and saved to `docs/plans/2026-02-27-batch-8-store-interfaces-plan.md`. Two execution options:

**1. Subagent-Driven (this session)** - I dispatch fresh subagent per task, review between tasks, fast iteration

**2. Parallel Session (separate)** - Open new session with `executeplan`, batch execution with checkpoints

Which approach?
