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.
463 lines
14 KiB
Markdown
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?
|