# Batch 5 (JetStream Errors) Design **Date:** 2026-02-27 **Scope:** Design for Batch 5 implementation planning only (206 features, 11 tests). ## Context Snapshot Batch metadata (`implementation_batches.id = 5`): - Batch ID: `5` - Name: `JetStream Errors` - Features: `206` - Tests: `11` - Dependencies: none - Go files: `server/jetstream_errors.go`, `server/jetstream_errors_generated.go` - Current status: all `206` features are `deferred`; all `11` tests are `deferred` Current code baseline: - `dotnet/src/ZB.MOM.NatsNet.Server/JetStream/JetStreamErrors.cs` already contains `203` static `JsApiError` constants. - Go has `203` generated `NewJS*Error` constructors. - C# currently exposes only `3` `NewJS*Error` methods: - `NewJSRestoreSubscribeFailedError` - `NewJSStreamRestoreError` - `NewJSPeerRemapError` - Batch 5 includes helper parity work from `jetstream_errors.go`: - `Unless` (already present) - `parseOpts` (mapped as `ParseOpts`) - `ApiError.toReplacerArgs` (mapped as `ToReplacerArgs`) ## Problem Statement Batch 5 is predominantly mechanical but high-risk for audit drift: 1. Method-surface gap is large (200 missing constructors). 2. Constructor signatures are mixed (no args, 1 arg, 2 args with placeholder replacement). 3. Existing test landscape includes deferred infra-heavy tests and impl-backlog stub patterns that must not be reused for verification. 4. PortTracker audit requires mapped method presence and evidence-backed status transitions. ## Constraints and Success Criteria Constraints: - Must follow .NET standards (xUnit 3 + Shouldly + NSubstitute; no FluentAssertions/Moq). - Must keep feature groups at max ~20 features each. - Must enforce strict anti-stub verification before status updates. - Must require passing related tests before setting features to `verified`. Success criteria: - All 206 Batch 5 feature mappings implemented with Go-behavior parity. - Constructor methods mirror Go semantics for `opts` override and placeholder substitution. - Verification evidence exists per feature group (build, focused tests, stub scan). - 11 mapped tests are either fully ported and passing, or explicitly kept deferred with concrete blocker reasons (no fake tests). ## Approaches ### Approach A: Manual method-by-method implementation Write all 200 missing `NewJS*Error` methods manually in `JetStreamErrors.cs`. - Pros: no generator tooling. - Cons: high typo risk, high audit drift risk, high review cost. ### Approach B: Full code generation from Go source for entire error file Generate both constants and constructors from Go into one fully generated C# file. - Pros: strongest parity with Go source. - Cons: higher one-time tooling complexity, risk of replacing hand-authored helpers/tests unexpectedly. ### Approach C (Recommended): Hybrid generation of constructor surface + hand-owned helper core Keep existing hand-owned constants/helpers in `JetStreamErrors.cs`, and generate/maintain a partial file containing all `NewJS*Error` constructors. Add focused tests validating constructor parity, override behavior, and placeholder replacement. - Pros: low-risk incremental adoption, deterministic method coverage, easier review per feature group. - Cons: requires a small generator script and disciplined grouped verification. ## Recommended Design ### 1. Class Structure - Keep `JsApiError` and base constants in existing file. - Split `JsApiErrors` into partial class files: - Hand-authored core (`Unless`, `ParseOpts`, `ToReplacerArgs`, `Clone`, `NewWithTags`, lookup methods) - Generated constructor surface (`NewJS*Error` methods) ### 2. Constructor Semantics For each generated constructor: - Parse `opts` and immediately return override when override is a `JsApiError`. - For non-templated descriptions, return canonical static error instance (or cloned equivalent where required by design/tests). - For templated descriptions, return a cloned instance with formatted `Description` using replacement args derived by `ToReplacerArgs` parity. - Type mapping: - Go `error` -> C# `Exception` - Go `interface{}` -> C# `object` - Go `uint64` -> C# `ulong` ### 3. Verification Architecture - Add/extend JetStream error unit tests for: - helper semantics (`Unless`, `ParseOpts`, replacement formatting) - constructor existence/signature consistency for all Batch 5 `NewJS*Error` methods - representative replacement-heavy constructors and known dependent constructors used by mapped tests - Keep infra-dependent tests deferred if server harness is unavailable; never replace with trivial passing tests. ### 4. Feature Grouping Strategy Implement and verify in 11 groups (<=20 features each) ordered by source line and tracker IDs: - Group 01: `1751,1752,1755,1756-1772` (20) - Group 02: `1773-1792` (20) - Group 03: `1793-1812` (20) - Group 04: `1813-1832` (20) - Group 05: `1833-1852` (20) - Group 06: `1853-1872` (20) - Group 07: `1873-1892` (20) - Group 08: `1893-1912` (20) - Group 09: `1913-1932` (20) - Group 10: `1933-1952` (20) - Group 11: `1953-1958` (6) ### 5. Test Handling Strategy for 11 Batch Tests Mapped tests: - `742`, `1304`, `1476`, `1606`, `1694`, `1696`, `1708`, `1757`, `1767`, `1777`, `2272` Design rule: - Attempt real ports where executable infrastructure exists. - If blocked by missing runtime server/cluster harness, keep `deferred` with specific reason and evidence; do not add fake assertions, empty non-skipped tests, or non-behavioral placeholders. ## Data Flow (Runtime) 1. Caller invokes `JsApiErrors.NewJS...Error(...)`. 2. Constructor evaluates `ParseOpts(opts)` for override. 3. If override contains `JsApiError`, return override clone. 4. Else clone canonical error constant. 5. For templated descriptions, apply replacements using `ToReplacerArgs` + replace pipeline. 6. Return `JsApiError` with stable `Code`, `ErrCode`, and resolved `Description`. ## Risks and Mitigations 1. **Large mechanical surface introduces silent mistakes** Mitigation: generated constructor file + grouped verification + reflection/parameterized tests. 2. **Audit mismatch due method naming/signature drift** Mitigation: source-of-truth method inventory from batch feature IDs and Go signatures. 3. **False confidence from placeholder tests** Mitigation: mandatory anti-stub scans and strict verification gates before status updates. 4. **Infra-heavy mapped tests block completion** Mitigation: explicit deferred protocol with reasoned notes; avoid fake completion. ## Approval-to-Plan Transition This design selects **Approach C (Hybrid generation + strict grouped verification)** and is ready for execution planning with mandatory verification protocol and anti-stub guardrails.