Files
natsnet/docs/plans/2026-02-27-batch-1-proto-const-ciphersuites-nkey-jwt-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

5.3 KiB

Batch 1 (Proto, Const, CipherSuites, NKey, JWT) Design

Date: 2026-02-27
Scope: Design only for implementing Batch 1 feature ports (10 features, 0 tracked tests).

Context Snapshot

Batch metadata (from porting.db):

  • Batch ID: 1
  • Name: Proto, Const, CipherSuites, NKey, JWT
  • Features: 10
  • Tests: 0
  • Dependencies: none
  • Go files: server/ciphersuites.go, server/const.go, server/jwt.go, server/nkey.go, server/proto.go

Feature IDs in this batch:

  • 384 init -> CipherSuites.Init
  • 583 init -> ServerConstants.Init
  • 1975 wipeSlice -> JwtProcessor.WipeSlice
  • 2441 Server.nonceRequired -> NatsServer.NonceRequiredInternal
  • 2593 protoScanField -> ProtoWire.ProtoScanField
  • 2594 protoScanTag -> ProtoWire.ProtoScanTag
  • 2595 protoScanFieldValue -> ProtoWire.ProtoScanFieldValue
  • 2596 protoScanVarint -> ProtoWire.ProtoScanVarint
  • 2597 protoScanBytes -> ProtoWire.ProtoScanBytes
  • 2598 protoEncodeVarint -> ProtoWire.ProtoEncodeVarint

Current Code Findings

  1. CipherSuites and ServerConstants use static constructors, but no explicit Init() method exists.
  2. JwtProcessor.WipeSlice does not exist; AuthHandler.WipeSlice exists.
  3. NatsServer.NonceRequiredInternal does not exist; NonceRequired() exists and is currently stubbed to false.
  4. ProtoWire behavior is largely implemented, but method names are currently Scan* / EncodeVarint, not ProtoScan* / ProtoEncodeVarint mapped in Batch 1.
  5. There are existing tests for CipherSuites and JwtProcessor, but no dedicated ProtoWire tests and no direct nonce-requirement tests.

Goals

  • Deliver full behavioral parity for the 10 Batch 1 features.
  • Align implementation names/signatures with tracker mappings so Roslyn audit can classify features correctly.
  • Add/extend tests where needed so features can be verified from evidence, not by assumption.

Non-Goals

  • No broader auth/JWT full claim-validation implementation beyond this batch's mapped functions.
  • No batch execution/status updates in this design document.
  • No unrelated refactors.

Approaches

Approach A: Tracker-name wrappers only (minimal)

Implement only mapped method names as wrappers around current code; avoid deeper behavior changes.

  • Pros: Fastest; lowest risk of regressions.
  • Cons: Could preserve existing behavioral drift (for example nonce logic), leaving hidden parity gaps.

Approach B: Full rename + strict parity rewrite

Rename existing methods to exact Go-style mapped names and reshape internals to match Go structure exactly.

  • Pros: Maximum parity and audit friendliness.
  • Cons: Higher churn and avoidable breakage risk for existing callers/tests.

Add mapped methods required by Batch 1 while preserving current call surfaces via wrappers or forwards, then close behavior gaps and strengthen tests.

  • Pros: Satisfies audit mapping and behavior with limited churn.
  • Cons: Slightly more code than Approach A.

1. API + Audit Alignment Layer

  • Add explicit Init() methods for CipherSuites and ServerConstants (idempotent warm-up semantics).
  • Add JwtProcessor.WipeSlice(Span<byte>) and keep compatibility with existing usages.
  • Add NatsServer.NonceRequiredInternal() (lock-held semantics) and call it from NonceRequired().
  • Add ProtoWire.ProtoScan* / ProtoEncodeVarint methods; keep existing Scan* / EncodeVarint as forwarding aliases if needed.

2. Behavior Parity Layer

  • Ensure nonce requirement logic matches Go intent:
    • AlwaysEnableNonce
    • configured nkeys present
    • trusted keys present
    • proxy key pairs present
  • Ensure proto varint and field scanners keep existing overflow/insufficient-data behavior at boundaries.

3. Verification Layer (Test-first)

  • Extend existing tests:
    • Auth/CipherSuitesTests.cs
    • Auth/JwtProcessorTests.cs
    • ServerTests.cs (or a dedicated nonce test file)
  • Add new focused tests for ProtoWire in dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Internal/ProtoWireTests.cs.
  • Keep xUnit 3 + Shouldly + NSubstitute only.

4. PortTracker Status Discipline

  • Move features through stub -> complete -> verified only after build + test evidence.
  • Use max 15 IDs per batch status update.
  • Store command output evidence in commit/task notes before updates.

Risks and Mitigations

  1. Audit false negatives due naming mismatch
    Mitigation: implement mapped method names explicitly (Init, WipeSlice, NonceRequiredInternal, Proto*).

  2. Regressions from changing existing method names
    Mitigation: prefer additive wrappers and keep old names temporarily where already referenced.

  3. Undertested low-level protobuf boundaries
    Mitigation: dedicated boundary tests for 1..10-byte varint decode and overflow paths.

  4. Stub creep under schedule pressure
    Mitigation: mandatory stub scans and hard gates in the implementation plan.

Success Criteria

  • All 10 Batch 1 features are implemented with mapped method presence and intended behavior.
  • Related tests pass and include explicit coverage for nonce logic and proto wire helpers.
  • No placeholder implementations (NotImplementedException, TODO stubs, empty methods) in touched feature/test files.
  • Batch 1 status can be advanced using evidence-based verification.