# 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 --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 "" --set-status stub --db porting.db --execute dotnet run --project tools/NatsNet.PortTracker -- \ feature batch-update --ids "" --set-status complete --db porting.db --execute dotnet run --project tools/NatsNet.PortTracker -- \ feature batch-update --ids "" --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 --status verified --db porting.db \ --override "manual verification evidence: " ``` ### 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 porting.db git commit -m "feat(batch8): " ``` --- ## 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 --status deferred --db porting.db \ --override "blocked: " dotnet run --project tools/NatsNet.PortTracker -- \ test update 1751 --status deferred --db porting.db \ --override "blocked: " ``` --- ### 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 " ``` **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?