# 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): ```bash dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \ --filter "FullyQualifiedName~." --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: ```bash 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) ```bash 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: ```bash dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~" --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): ```bash dotnet run --project tools/NatsNet.PortTracker -- \ feature batch-update --ids "" --set-status complete --db porting.db --execute dotnet run --project tools/NatsNet.PortTracker -- \ feature batch-update --ids "" --set-status verified --db porting.db --execute ``` If audit rejects a valid status, re-run with explicit reason: ```bash dotnet run --project tools/NatsNet.PortTracker -- \ feature update --status verified --db porting.db --override "manual verification evidence: " ``` ### Checkpoint Protocol Between Tasks (REQUIRED) After each task group (A/B/C/D), before starting the next: 1. Full build: ```bash dotnet build dotnet/ ``` 2. Full unit test suite: ```bash 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: ```bash dotnet run --project tools/NatsNet.PortTracker -- \ feature update --status deferred --db porting.db --override "blocked: " ``` --- ### 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`)** ```bash 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** ```bash 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** ```bash 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)** ```bash 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`** ```bash 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)` 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** ```bash 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** ```bash 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`** ```bash 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** ```bash 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** ```bash 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** ```bash 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`** ```bash 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** ```bash 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** ```bash 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** ```bash 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** ```bash 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** ```bash dotnet run --project tools/NatsNet.PortTracker -- audit --type features --db porting.db ``` If dry-run is clean, apply: ```bash dotnet run --project tools/NatsNet.PortTracker -- audit --type features --db porting.db --execute ``` **Step 4: Close batch** ```bash dotnet run --project tools/NatsNet.PortTracker -- batch complete 1 --db porting.db ``` **Step 5: Report + final commit** ```bash ./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" ```