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

14 KiB

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:
    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:
    dotnet build dotnet/
    
  5. Run related tests for that feature slice:
    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:

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)

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:

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:

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:

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:
    dotnet build dotnet/
    
  2. Full unit tests:
    dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --verbosity normal
    
  3. Commit task slice:
    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:

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)

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

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

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

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)

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

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

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

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

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

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)

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

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

Step 6: Run checkpoint protocol and commit

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

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

Step 2: Confirm all Batch 8 IDs are closed correctly

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

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

Step 4: Regenerate report and commit closure artifacts

./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?