Files
natsnet/docs/plans/2026-02-27-batch-5-jetstream-errors-design.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

6.6 KiB

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.

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.

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.