# Batch 8 (Store Interfaces) Design **Date:** 2026-02-27 **Scope:** Batch 8 planning only (27 features, 1 tracked test) for `server/store.go` parity. ## Context Snapshot Batch metadata (from PortTracker): - Batch ID: `8` - Name: `Store Interfaces` - Features: `27` - Tests: `1` - Dependencies: none - Go source: `server/store.go` - Current status: all `27` features and test `1751` are `deferred` Targeted feature clusters: - Stream-state codec/parsing and delete-block state helpers (`IsEncodedStreamState`, `DecodeStreamState`, `DeleteRange.State`, `DeleteSlice.State`) - Consumer state encoding (`encodeConsumerState`) - Enum JSON/string parity for `RetentionPolicy`, `DiscardPolicy`, `StorageType`, `AckPolicy`, `ReplayPolicy`, `DeliverPolicy` - Store/runtime helpers (`isOutOfSpaceErr`, `isClusterResetErr`, `StoreMsg.copy`, `bytesToString`, `stringToBytes`, `copyString`, `isPermissionError`) Tracked test in this batch: - `unit_test #1751` (`TestJetStreamDirectGetUpToTime` -> `.NET: JetStreamEngineTests.JetStreamDirectGetUpToTime_ShouldSucceed`) - Depends on feature `3191` (`bytesToString`) plus already-verified features (`325`, `804`, `2474`, `2483`, `3051`) ## Problem Statement `StoreTypes.cs` already defines many store types and interfaces, but Batch 8 parity methods are still unverified/deferred. The risk is twofold: 1. Behavior gaps: binary decode/encode parity, enum JSON text parity, and byte/string helpers can silently diverge from Go semantics. 2. Audit/status drift: mapped feature names require explicit, test-backed evidence before transitioning from `deferred` to `verified`. ## Constraints and Success Criteria Constraints: - .NET 10 + C# latest with nullable enabled - xUnit 3 + Shouldly + NSubstitute only - No stubs/fake tests for status promotion - Batch/task grouping must stay <= ~20 features per task Success criteria: - All 27 feature mappings implemented or mapped with explicit wrappers/adapters and verified by related tests. - One tracked test (`1751`) is either truly passing or explicitly deferred with concrete blocker evidence. - PortTracker statuses updated in evidence-backed chunks with strict verification gates. ## Approaches ### Approach A: Minimal wrappers to satisfy mapped method names Add thin wrappers only (for mapped member names), keep most logic unchanged. - Pros: fast mapping closure. - Cons: high risk of semantic mismatch; weak confidence in parity. ### Approach B: Full parity refactor inside `StoreTypes.cs` Rework all Batch 8 behavior directly in existing types and enums, including JSON handling and helpers. - Pros: strongest parity in one place. - Cons: high change surface in a core file; harder review/debug cycle. ### Approach C (Recommended): Focused parity layer with targeted tests Keep existing `StoreTypes.cs` types stable, add explicit parity methods/wrappers where needed, and add a dedicated test class that validates each mapped behavior from `store.go`. - Pros: controlled change scope, strong evidence, easier audit and rollback. - Cons: requires careful method-shape decisions for enum/string/JSON mappings. ## Recommended Design ### 1. Production Code Layout Primary touchpoint: - `dotnet/src/ZB.MOM.NatsNet.Server/JetStream/StoreTypes.cs` If needed to keep `StoreTypes.cs` readable, allow one focused helper file: - `dotnet/src/ZB.MOM.NatsNet.Server/JetStream/StoreParity.cs` (or similarly named) Design intent: - Implement stream-state decode and encoding helpers with Go-equivalent error handling (`ErrBadStreamStateEncoding`, `ErrCorruptStreamState`). - Add explicit state methods/parity wrappers for delete blocks and `StoreMsg.copy` semantics. - Implement enum string/JSON parity through explicit methods and/or converters that preserve Go wire values (`"limits"`, `"new"`, `"memory"`, etc.). - Implement utility predicates/helpers exactly for Batch 8 semantics. ### 2. Test Design Primary new test file: - `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/JetStream/StoreTypesTests.cs` Test coverage split: - Codec tests: encoded-stream header detection, decode success/failure paths, corrupt payload handling. - Delete-block tests: `State()` and `Range()` behavior parity. - Consumer-state encoding tests: deterministic structural assertions (header, key fields, pending/redelivery shape). - Enum tests: string and JSON round-trip coverage, invalid input failures. - Helper tests: out-of-space/cluster-reset predicates, byte/string conversion and copy isolation, permission error predicate. Tracked test handling: - Add/port `JetStreamDirectGetUpToTime_ShouldSucceed` in `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/JetStreamEngineTests.Impltests.cs` only if it can be made real and executable. - If environment/runtime dependencies block realism, keep `#1751` deferred with explicit evidence and reason; do not add a fake-pass test. ### 3. Execution Slicing Use two feature groups (both <=20 IDs): - Group A (12 features): `3164,3165,3166,3168,3171,3187,3188,3189,3191,3192,3193,3194` - Group B (15 features): `3172,3173,3174,3175,3176,3177,3178,3179,3180,3181,3182,3183,3184,3185,3186` Then handle tracked test `1751` as a separate task. ### 4. Risks and Mitigations 1. Enum method-shape mismatch with C# enums vs Go methods Mitigation: use explicit parity methods/extensions and validate via tracker audit + tests. 2. Binary decode edge cases (varint parsing/corrupt payloads) Mitigation: table-driven tests using known-good and intentionally malformed byte payloads. 3. Existing ImplBacklog test quality is low Mitigation: strict anti-stub policy; only behavior-based assertions count toward verification. 4. Direct-get test may require broader server runtime not yet ported Mitigation: defer with concrete blocker evidence instead of fake implementation. ## Design Decision Choose **Approach C**: implement Batch 8 via a focused parity layer plus dedicated targeted tests, executed in two feature groups and one test task with strict status-evidence gates.