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.
161 lines
6.6 KiB
Markdown
161 lines
6.6 KiB
Markdown
# 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.
|