Files
natsnet/docs/plans/2026-02-27-batch-8-store-interfaces-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

463 lines
14 KiB
Markdown

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