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

15 KiB

Batch 1 (Proto, Const, CipherSuites, NKey, JWT) Implementation Plan

For Codex: REQUIRED SUB-SKILL: Use executeplan to implement this plan task-by-task.

Goal: Implement and verify all 10 Batch 1 feature mappings with audit-aligned method names and behavior-faithful .NET parity.

Architecture: Use a hybrid compatibility approach: add/align mapped methods required by PortTracker (Init, WipeSlice, NonceRequiredInternal, Proto*) while preserving existing callers via wrappers where needed. Execute in four feature groups with strict per-feature red/green loops, then close the batch via evidence-backed status updates.

Tech Stack: .NET 10, C# latest, xUnit 3, Shouldly, NSubstitute, PortTracker CLI, SQLite (porting.db)

Design doc: docs/plans/2026-02-27-batch-1-proto-const-ciphersuites-nkey-jwt-design.md


Batch 1 Working Set

Feature groups (max group size <= 20 features):

  • Group A (2 features): 384, 583
  • Group B (2 features): 1975, 2441
  • Group C (5 features): 2593, 2594, 2595, 2596, 2597
  • Group D (1 feature): 2598

Batch facts:

  • Total features: 10
  • Total tracked tests: 0
  • Dependency batches: none

MANDATORY VERIFICATION PROTOCOL

NON-NEGOTIABLE: every feature in this batch must pass this loop before status advancement.

What Counts as a Real Feature Verification

A feature is eligible for verified only when all are true:

  1. Mapped .NET method exists on mapped class (dotnet_class.dotnet_method).
  2. Behavior matches Go intent for the mapped function.
  3. Related tests execute and pass (not merely discovered as zero tests).
  4. No stub markers remain in touched feature/test files.
  5. Build is green after the feature group.

Per-Feature Verification Loop (REQUIRED for each feature ID)

  1. Read exact Go source range from tracker mapping.
  2. Write or adjust C# implementation in mapped class/method.
  3. Write or update a focused test that exercises the behavior.
  4. Run focused test(s):
    dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
      --filter "FullyQualifiedName~<ClassName>.<MethodOrScenario>" --verbosity normal
    
  5. Verify summary shows at least 1 executed test and 0 failures.
  6. Run build gate (dotnet build dotnet/) before promoting group statuses.

Stub Detection Check (REQUIRED after each feature group)

Run against touched source and tests:

rg -n "NotImplementedException|throw new NotSupportedException\(" dotnet/src/ZB.MOM.NatsNet.Server dotnet/tests/ZB.MOM.NatsNet.Server.Tests
rg -n "TODO|PLACEHOLDER|Assert\.True\(true\)|Assert\.Pass\(|ShouldBe\(true\);$|^\s*\{\s*\}$" dotnet/tests/ZB.MOM.NatsNet.Server.Tests

Any hit in edited files blocks status updates until fixed or explicitly deferred.

Build Gate (REQUIRED after each feature group)

dotnet build dotnet/

Required: build succeeds with 0 errors.

Test Gate (REQUIRED before marking any feature verified)

  • Run all related test classes for the group (existing + newly added).
  • For this batch, related classes include at minimum:
    • ZB.MOM.NatsNet.Server.Tests.Auth.CipherSuitesTests
    • ZB.MOM.NatsNet.Server.Tests.Auth.JwtProcessorTests
    • ZB.MOM.NatsNet.Server.Tests.Auth.JwtProcessorOperatorTests
    • ZB.MOM.NatsNet.Server.Tests.ServerTests (or dedicated nonce test class)
    • ZB.MOM.NatsNet.Server.Tests.Internal.ProtoWireTests (new)

Run pattern:

dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~<ClassName>" --verbosity normal

Required: all related class runs pass with Failed: 0.

Status Update Protocol

  • Use max 15 IDs per feature batch-update command.
  • Never set verified without captured build + test evidence.
  • Status flow per feature: deferred/not_started -> stub -> complete -> verified.
  • Record evidence per update chunk (command + pass summary + files touched).

Commands (chunk size max 15):

dotnet run --project tools/NatsNet.PortTracker -- \
  feature batch-update --ids "<ids>" --set-status complete --db porting.db --execute

dotnet run --project tools/NatsNet.PortTracker -- \
  feature batch-update --ids "<ids>" --set-status verified --db porting.db --execute

If audit rejects a valid status, re-run with explicit reason:

dotnet run --project tools/NatsNet.PortTracker -- \
  feature update <id> --status verified --db porting.db --override "manual verification evidence: <short reason>"

Checkpoint Protocol Between Tasks (REQUIRED)

After each task group (A/B/C/D), before starting the next:

  1. Full build:
    dotnet build dotnet/
    
  2. Full unit test suite:
    dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --verbosity normal
    
  3. Confirm total summary is stable and no new failures introduced.
  4. Commit the group before moving on.

ANTI-STUB GUARDRAILS (NON-NEGOTIABLE)

Forbidden Patterns

The following are forbidden in touched feature or test code:

  • throw new NotImplementedException()
  • Empty method bodies used as placeholders
  • TODO, PLACEHOLDER, or similar deferred markers without status deferral
  • Fake-pass tests (Assert.True(true), Assert.Pass(), meaningless single assert)
  • Dummy return values used to bypass behavior (return default, return null) without Go-equivalent logic

Hard Limits

  • Max 15 IDs per status update command.
  • Max 1 feature group promoted per verification cycle.
  • Mandatory build + related test evidence before verified.
  • Mandatory checkpoint commit after each group.

If You Get Stuck

Do not stub.

  1. Leave/return feature status as deferred.
  2. Add explicit tracker override reason describing the concrete blocker.
  3. Commit only proven work.
  4. Continue with next unblocked feature in the current group.

Example:

dotnet run --project tools/NatsNet.PortTracker -- \
  feature update <id> --status deferred --db porting.db --override "blocked: <specific runtime or API gap>"

Task 1: Group A - Init Parity (Features 384, 583)

Files:

  • Modify: dotnet/src/ZB.MOM.NatsNet.Server/Auth/CipherSuites.cs
  • Modify: dotnet/src/ZB.MOM.NatsNet.Server/ServerConstants.cs
  • Modify: dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Auth/CipherSuitesTests.cs
  • Modify: dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ServerTests.cs (or add focused constants test file)

Step 1: Mark feature IDs as in-progress (stub)

dotnet run --project tools/NatsNet.PortTracker -- \
  feature batch-update --ids "384,583" --set-status stub --db porting.db --execute

Step 2: Write failing tests for explicit init hooks

Add tests asserting CipherSuites.Init() and ServerConstants.Init() are callable and idempotent.

Step 3: Run focused tests and confirm FAIL

dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~CipherSuitesTests" --verbosity normal

Step 4: Implement minimal production code to pass

Add explicit mapped methods:

  • CipherSuites.Init()
  • ServerConstants.Init()

Both must be idempotent and preserve existing behavior.

Step 5: Re-run focused tests and confirm PASS

Run both related classes and confirm zero failures.

Step 6: Run mandatory stub scan + build gate

Use the protocol commands above.

Step 7: Promote statuses with evidence

dotnet run --project tools/NatsNet.PortTracker -- \
  feature batch-update --ids "384,583" --set-status complete --db porting.db --execute

dotnet run --project tools/NatsNet.PortTracker -- \
  feature batch-update --ids "384,583" --set-status verified --db porting.db --execute

Step 8: Checkpoint (full build + full unit tests + commit)

git add dotnet/src/ZB.MOM.NatsNet.Server/Auth/CipherSuites.cs \
        dotnet/src/ZB.MOM.NatsNet.Server/ServerConstants.cs \
        dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Auth/CipherSuitesTests.cs \
        dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ServerTests.cs \
        porting.db

git commit -m "feat(batch1): add init parity hooks for ciphers and constants"

Task 2: Group B - JWT + NKey Nonce Helpers (Features 1975, 2441)

Files:

  • Modify: dotnet/src/ZB.MOM.NatsNet.Server/Auth/JwtProcessor.cs
  • Modify: dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Listeners.cs
  • Modify: dotnet/src/ZB.MOM.NatsNet.Server/Auth/AuthHandler.cs (only if retaining compatibility wrapper)
  • Modify: dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Auth/JwtProcessorTests.cs
  • Modify/Create: dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Server/NonceRequiredTests.cs (or equivalent in ServerTests.cs)

Step 1: Mark IDs as stub

dotnet run --project tools/NatsNet.PortTracker -- \
  feature batch-update --ids "1975,2441" --set-status stub --db porting.db --execute

Step 2: Write failing tests

  • JwtProcessor.WipeSlice fills buffer with 'x'.
  • NonceRequiredInternal returns true for each Go condition and false otherwise.

Step 3: Run focused tests and confirm FAIL

Run JwtProcessorTests and nonce-focused tests.

Step 4: Implement minimal code

  • Add JwtProcessor.WipeSlice(Span<byte>) and route existing call sites as needed.
  • Implement NatsServer.NonceRequiredInternal() using:
    • GetOpts().AlwaysEnableNonce
    • _nkeys?.Count > 0
    • _trustedKeys != null
    • _proxiesKeyPairs.Count > 0

Step 5: Re-run focused tests and confirm PASS

Step 6: Stub scan + build gate

Step 7: Promote statuses

dotnet run --project tools/NatsNet.PortTracker -- \
  feature batch-update --ids "1975,2441" --set-status complete --db porting.db --execute

dotnet run --project tools/NatsNet.PortTracker -- \
  feature batch-update --ids "1975,2441" --set-status verified --db porting.db --execute

Step 8: Checkpoint + commit

git add dotnet/src/ZB.MOM.NatsNet.Server/Auth/JwtProcessor.cs \
        dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Listeners.cs \
        dotnet/src/ZB.MOM.NatsNet.Server/Auth/AuthHandler.cs \
        dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Auth/JwtProcessorTests.cs \
        dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Server/NonceRequiredTests.cs \
        porting.db

git commit -m "feat(batch1): implement jwt wipe and nonce-required internal logic"

Task 3: Group C - Proto Scan Helpers (Features 2593-2597)

Files:

  • Modify: dotnet/src/ZB.MOM.NatsNet.Server/Internal/ProtoWire.cs
  • Create: dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Internal/ProtoWireTests.cs

Step 1: Mark IDs as stub

dotnet run --project tools/NatsNet.PortTracker -- \
  feature batch-update --ids "2593,2594,2595,2596,2597" --set-status stub --db porting.db --execute

Step 2: Write failing tests for mapped scan methods

Cover:

  • valid/invalid tag decode
  • unsupported wire type error
  • insufficient data behavior
  • overflow behavior in varint decode
  • length-delimited size behavior

Step 3: Run focused tests and confirm FAIL

dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~ProtoWireTests" --verbosity normal

Step 4: Implement minimal mapped methods

Add mapped methods:

  • ProtoScanField
  • ProtoScanTag
  • ProtoScanFieldValue
  • ProtoScanVarint
  • ProtoScanBytes

Use existing logic or direct forwards without changing behavior.

Step 5: Re-run ProtoWire tests and confirm PASS

Step 6: Stub scan + build gate

Step 7: Promote statuses

dotnet run --project tools/NatsNet.PortTracker -- \
  feature batch-update --ids "2593,2594,2595,2596,2597" --set-status complete --db porting.db --execute

dotnet run --project tools/NatsNet.PortTracker -- \
  feature batch-update --ids "2593,2594,2595,2596,2597" --set-status verified --db porting.db --execute

Step 8: Checkpoint + commit

git add dotnet/src/ZB.MOM.NatsNet.Server/Internal/ProtoWire.cs \
        dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Internal/ProtoWireTests.cs \
        porting.db

git commit -m "feat(batch1): add mapped proto scan helpers with boundary tests"

Task 4: Group D - Proto Varint Encode (Feature 2598)

Files:

  • Modify: dotnet/src/ZB.MOM.NatsNet.Server/Internal/ProtoWire.cs
  • Modify: dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Internal/ProtoWireTests.cs

Step 1: Mark ID as stub

dotnet run --project tools/NatsNet.PortTracker -- \
  feature update 2598 --status stub --db porting.db

Step 2: Write failing tests for ProtoEncodeVarint boundaries

Cover 1<<7, 1<<14, ..., 1<<63 edges and encode/decode round-trip with ProtoScanVarint.

Step 3: Run focused tests and confirm FAIL

Step 4: Implement minimal code

Add ProtoEncodeVarint mapped method (forward or primary implementation) with 10-byte max semantics matching Go.

Step 5: Re-run focused tests and confirm PASS

Step 6: Stub scan + build gate

Step 7: Promote status

dotnet run --project tools/NatsNet.PortTracker -- \
  feature update 2598 --status complete --db porting.db

dotnet run --project tools/NatsNet.PortTracker -- \
  feature update 2598 --status verified --db porting.db

Step 8: Checkpoint + commit

git add dotnet/src/ZB.MOM.NatsNet.Server/Internal/ProtoWire.cs \
        dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Internal/ProtoWireTests.cs \
        porting.db

git commit -m "feat(batch1): implement proto varint encoder parity"

Task 5: Batch 1 Final Verification and Closure

Files:

  • Modify: porting.db
  • Generate: reports/current.md (optional at end of batch)

Step 1: Full regression gates

dotnet build dotnet/
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --verbosity normal

Required: Failed: 0.

Step 2: Final stub audit on touched files

rg -n "NotImplementedException|TODO|PLACEHOLDER|Assert\.True\(true\)|Assert\.Pass\(" \
  dotnet/src/ZB.MOM.NatsNet.Server/Auth/CipherSuites.cs \
  dotnet/src/ZB.MOM.NatsNet.Server/ServerConstants.cs \
  dotnet/src/ZB.MOM.NatsNet.Server/Auth/JwtProcessor.cs \
  dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Listeners.cs \
  dotnet/src/ZB.MOM.NatsNet.Server/Internal/ProtoWire.cs \
  dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Auth/CipherSuitesTests.cs \
  dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Auth/JwtProcessorTests.cs \
  dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Server/NonceRequiredTests.cs \
  dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Internal/ProtoWireTests.cs

Required: no matches.

Step 3: Audit feature mapping resolution

dotnet run --project tools/NatsNet.PortTracker -- audit --type features --db porting.db

If dry-run is clean, apply:

dotnet run --project tools/NatsNet.PortTracker -- audit --type features --db porting.db --execute

Step 4: Close batch

dotnet run --project tools/NatsNet.PortTracker -- batch complete 1 --db porting.db

Step 5: Report + final commit

./reports/generate-report.sh

git add dotnet/src/ZB.MOM.NatsNet.Server \
        dotnet/tests/ZB.MOM.NatsNet.Server.Tests \
        porting.db reports/current.md

git commit -m "feat(batch1): complete proto/const/ciphers/nkey/jwt feature set"