# Batch 16 (Client Core first half) Implementation Plan > **For Codex:** REQUIRED SUB-SKILL: Use `executeplan` to implement this plan task-by-task. **Goal:** Implement and verify Batch 16 (`server/client.go` first half) feature parity in two controlled feature groups (30 features total) and resolve the single tracked test (`#2859`) with real evidence or explicit deferral. **Architecture:** Use a staged porting model: deterministic helper features first, then outbound/parser-state features. Keep `ClientConnection` as the primary host, reuse existing parser logic in `ProtocolParser`, and enforce strict per-feature verification loops to prevent stub regressions. Batch status updates happen only after group-level build and test gates. **Tech Stack:** .NET 10, C# latest, xUnit 3, Shouldly, NSubstitute, PortTracker CLI, SQLite (`porting.db`) **Design doc:** `docs/plans/2026-02-27-batch-16-client-core-first-half-design.md` --- ## Batch 16 Working Set - **Total features:** `30` - **Total tests:** `1` - **Dependencies:** batches `2`, `3`, `4` - **Go source:** `golang/nats-server/server/client.go` Feature groups (max size <= 20): - **Group A (19 features):** `387,388,389,390,391,392,393,394,395,396,397,398,402,411,420,421,422,423,424` - **Group B (11 features):** `429,430,431,432,456,471,472,473,474,475,476` Tracked test: - **Test:** `2859` (`RouteHandlerTests.RouteSlowConsumerRecover_ShouldSucceed`) --- ## MANDATORY VERIFICATION PROTOCOL > **NON-NEGOTIABLE:** Every feature and test in this batch must pass these gates before any `verified` status update. ### What Counts as Real Verification A feature/test is eligible for `verified` only when all conditions hold: 1. Mapped .NET method exists and contains real logic (no placeholder body). 2. Behavior matches Go intent for the mapped function/test scenario. 3. Focused related tests run and pass with non-zero executed tests. 4. Stub scan returns zero hits in touched files. 5. Group build and group test gates are green. ### Per-Feature Verification Loop (REQUIRED for each feature ID) 1. Read exact Go source range from tracker: ```bash dotnet run --project tools/NatsNet.PortTracker -- feature show --db porting.db ``` 2. Open Go function in `golang/nats-server/server/client.go` and capture intended behavior. 3. Write or update C# implementation in mapped .NET target file. 4. Run build and related focused tests: ```bash dotnet build dotnet/ dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~" --verbosity normal ``` 5. Verify summary reports at least one executed test and `Failed: 0`. 6. Add feature ID to group-ready evidence list only after green build + green focused tests. ### Stub Detection Check (REQUIRED after each feature group and test task) Run on all touched source and test files: ```bash grep -R -n -E "NotImplementedException|TODO|PLACEHOLDER" \ dotnet/src/ZB.MOM.NatsNet.Server \ dotnet/tests/ZB.MOM.NatsNet.Server.Tests grep -R -n -E "^[[:space:]]*(public|internal|private|protected)[^;]*\\)\\s*\\{[[:space:]]*\\}$" \ dotnet/src/ZB.MOM.NatsNet.Server \ dotnet/tests/ZB.MOM.NatsNet.Server.Tests ``` Any hit in touched files blocks status promotion until fixed or explicitly deferred with reason. ### Build Gate (REQUIRED after each feature group) ```bash dotnet build dotnet/ ``` Required: `0` errors. ### Test Gate (REQUIRED before marking features `verified`) Run all related classes for the group: ```bash dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~ClientTests" --verbosity normal dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~ClientConnectionStubFeaturesTests" --verbosity normal dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~ProtocolParserTests" --verbosity normal dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~RouteHandlerTests" --verbosity normal ``` Required: all relevant runs show `Failed: 0` and non-zero executed tests for newly touched scenarios. ### Status Update Protocol (REQUIRED) 1. **Max 15 IDs per `feature batch-update` or `test batch-update` command.** 2. Status flow per item: `deferred/not_started -> stub -> complete -> verified` (or `deferred` with reason). 3. Every update chunk must have evidence: - go source reviewed - build output - related test output - stub scan output 4. If audit disagrees and logic is proven, use explicit override reason. Template commands: ```bash dotnet run --project tools/NatsNet.PortTracker -- \ feature batch-update --ids "<<=15 ids>" --set-status stub --db porting.db --execute dotnet run --project tools/NatsNet.PortTracker -- \ feature batch-update --ids "<<=15 ids>" --set-status complete --db porting.db --execute dotnet run --project tools/NatsNet.PortTracker -- \ feature batch-update --ids "<<=15 ids>" --set-status verified --db porting.db --execute ``` ### Checkpoint Protocol Between Tasks (REQUIRED) After each major task group (Group A, Group B, test task): 1. Full build: ```bash dotnet build dotnet/ ``` 2. Full unit tests: ```bash dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --verbosity normal ``` 3. Confirm no new regressions. 4. Commit before moving to next task. --- ## ANTI-STUB GUARDRAILS (NON-NEGOTIABLE) ### Forbidden Patterns The following are forbidden in touched feature/test code: - `throw new NotImplementedException()` - `TODO` / `PLACEHOLDER` markers left in executable paths - Empty method bodies used as placeholders (`{ }`) - Trivial always-pass assertions (`Assert.True(true)`, equivalent fake checks) - Wrapper methods that ignore Go behavior and return dummy values ### Hard Limits - Max `15` IDs per status-update command. - Max `1` feature group promoted per verification cycle. - Mandatory stub scan + build gate + test gate before each promotion. - Mandatory checkpoint commit between task groups. - No "temporary stubs" allowed for batch completion. ### If You Get Stuck Do **not** stub. Use this exact path: 1. Keep/return blocked feature or test to `deferred`. 2. Add explicit reason via override (specific missing infra/dependency). 3. Commit only proven items. 4. Continue with next unblocked item in current group. Examples: ```bash dotnet run --project tools/NatsNet.PortTracker -- \ feature update --status deferred --db porting.db --override "blocked: requires " dotnet run --project tools/NatsNet.PortTracker -- \ test update --status deferred --db porting.db --override "blocked: requires " ``` --- ### Task 1: Preflight, Dependency Gate, and Mapping Hygiene **Files:** - Modify (if needed): `porting.db` mappings for impossible enum-hosted method targets - Inspect: `golang/nats-server/server/client.go` **Step 1: Confirm batch readiness** ```bash dotnet run --project tools/NatsNet.PortTracker -- batch ready --db porting.db dotnet run --project tools/NatsNet.PortTracker -- batch show 16 --db porting.db ``` Expected: Batch 16 appears as ready. If not ready, stop execution and keep this batch pending. **Step 2: Start batch** ```bash dotnet run --project tools/NatsNet.PortTracker -- batch start 16 --db porting.db ``` **Step 3: Reconcile method-host mappings where class type cannot host methods** Focus on enum-hosted mappings (`ClientFlags`, `ReadCacheFlags`, `WriteTimeoutPolicy.String`). Use `feature map` / `feature batch-map` only if required for auditable method hosting. **Step 4: Commit mapping-only changes (if any)** ```bash git add porting.db git commit -m "chore(batch16): reconcile feature mappings for verifiable method hosts" ``` --- ### Task 2: Group A Features (19) - Helpers, Flags, Permissions, Expiration **Feature IDs:** `387,388,389,390,391,392,393,394,395,396,397,398,402,411,420,421,422,423,424` **Files:** - Modify: `dotnet/src/ZB.MOM.NatsNet.Server/ClientConnection.cs` - Modify: `dotnet/src/ZB.MOM.NatsNet.Server/ClientTypes.cs` - Modify: `dotnet/src/ZB.MOM.NatsNet.Server/ServerOptionTypes.cs` - Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ClientTests.cs` - Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ClientConnectionStubFeaturesTests.cs` **Step 1: Mark Group A as `stub` in chunks <= 15** ```bash dotnet run --project tools/NatsNet.PortTracker -- \ feature batch-update --ids "387,388,389,390,391,392,393,394,395,396,397,398,402,411,420" --set-status stub --db porting.db --execute dotnet run --project tools/NatsNet.PortTracker -- \ feature batch-update --ids "421,422,423,424" --set-status stub --db porting.db --execute ``` **Step 2: Write failing tests for Group A behavior** - Add/extend tests for: - internal-client classification - flag set/clear/isSet/setIfNotSet semantics - timeout policy string value - nb pool get/put behavior - TLS state accessor and kind accessor - public/deny permissions merge behavior - expiration and deny-filter loading behavior **Step 3: Run focused tests and confirm failures** ```bash dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~ClientTests" --verbosity normal dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~ClientConnectionStubFeaturesTests" --verbosity normal ``` **Step 4: Implement minimal behavior-faithful Group A production code** Apply per-feature loop from protocol section for all 19 IDs. **Step 5: Run focused tests until green** Re-run the two related classes and verify `Failed: 0`. **Step 6: Mandatory stub scan + build gate** Run required stub and build commands from protocol section. **Step 7: Promote Group A statuses with evidence (<=15 IDs/chunk)** ```bash dotnet run --project tools/NatsNet.PortTracker -- \ feature batch-update --ids "387,388,389,390,391,392,393,394,395,396,397,398,402,411,420" --set-status complete --db porting.db --execute dotnet run --project tools/NatsNet.PortTracker -- \ feature batch-update --ids "421,422,423,424" --set-status complete --db porting.db --execute dotnet run --project tools/NatsNet.PortTracker -- \ feature batch-update --ids "387,388,389,390,391,392,393,394,395,396,397,398,402,411,420" --set-status verified --db porting.db --execute dotnet run --project tools/NatsNet.PortTracker -- \ feature batch-update --ids "421,422,423,424" --set-status verified --db porting.db --execute ``` **Step 8: Checkpoint protocol + commit** ```bash git add dotnet/src/ZB.MOM.NatsNet.Server/ClientConnection.cs \ dotnet/src/ZB.MOM.NatsNet.Server/ClientTypes.cs \ dotnet/src/ZB.MOM.NatsNet.Server/ServerOptionTypes.cs \ dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ClientTests.cs \ dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ClientConnectionStubFeaturesTests.cs \ porting.db git commit -m "feat(batch16): port client helper and permission core features" ``` --- ### Task 3: Group B Features (11) - Outbound Pipeline and Pub/Sub Parsing **Feature IDs:** `429,430,431,432,456,471,472,473,474,475,476` **Files:** - Modify: `dotnet/src/ZB.MOM.NatsNet.Server/ClientConnection.cs` - Modify: `dotnet/src/ZB.MOM.NatsNet.Server/Protocol/ProtocolParser.cs` (only if parser helper exposure is needed) - Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ClientConnectionStubFeaturesTests.cs` - Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Protocol/ProtocolParserTests.cs` **Step 1: Mark Group B as `stub`** ```bash dotnet run --project tools/NatsNet.PortTracker -- \ feature batch-update --ids "429,430,431,432,456,471,472,473,474,475,476" --set-status stub --db porting.db --execute ``` **Step 2: Write failing tests for outbound and parser wrappers** - Outbound queue growth/chunking and pending-byte accounting. - Flush behavior under partial writes and timeout error paths. - `HandleWriteTimeout` and `MarkConnAsClosed` reason-specific transitions. - `ProcessHeaderPub`, `ProcessPub`, `SplitArg`, `ParseSub`, `ProcessSub`, `ProcessSubEx` behavior. **Step 3: Run focused tests and confirm failures** ```bash dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~ClientConnectionStubFeaturesTests" --verbosity normal dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~ProtocolParserTests" --verbosity normal ``` **Step 4: Implement Group B features with per-feature verification loop** Port from Go source ranges, reusing `ProtocolParser` behavior where valid. **Step 5: Re-run focused tests until green** Same two test runs, verify `Failed: 0`. **Step 6: Stub scan + build gate + related test gate** Run protocol-mandated commands. **Step 7: Promote Group B statuses** ```bash dotnet run --project tools/NatsNet.PortTracker -- \ feature batch-update --ids "429,430,431,432,456,471,472,473,474,475,476" --set-status complete --db porting.db --execute dotnet run --project tools/NatsNet.PortTracker -- \ feature batch-update --ids "429,430,431,432,456,471,472,473,474,475,476" --set-status verified --db porting.db --execute ``` **Step 8: Checkpoint protocol + commit** ```bash git add dotnet/src/ZB.MOM.NatsNet.Server/ClientConnection.cs \ dotnet/src/ZB.MOM.NatsNet.Server/Protocol/ProtocolParser.cs \ dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ClientConnectionStubFeaturesTests.cs \ dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Protocol/ProtocolParserTests.cs \ porting.db git commit -m "feat(batch16): port outbound and parser-facing client core features" ``` --- ### Task 4: Batch Test #2859 (`TestRouteSlowConsumerRecover`) **Test ID:** `2859` **Files:** - Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/RouteHandlerTests.Impltests.cs` - Inspect dependencies via `porting.db` before status decision **Step 1: Mark test as `stub` only if implementation attempt begins** ```bash dotnet run --project tools/NatsNet.PortTracker -- \ test update 2859 --status stub --db porting.db ``` **Step 2: Port Go test intent to C# and run focused test** ```bash dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \ --filter "FullyQualifiedName~RouteHandlerTests.RouteSlowConsumerRecover_ShouldSucceed" \ --verbosity normal ``` **Step 3: Decision gate** - If test is green with real assertions and real behavior coverage: - set `complete`, then `verified`. - If blocked by unmet runtime/dependency constraints: - set back to `deferred` with explicit reason (for example unresolved dependency `#1207` or missing route/network harness behavior). **Step 4: Apply status update with evidence** ```bash dotnet run --project tools/NatsNet.PortTracker -- \ test update 2859 --status verified --db porting.db ``` or ```bash dotnet run --project tools/NatsNet.PortTracker -- \ test update 2859 --status deferred --db porting.db --override "blocked: " ``` **Step 5: Checkpoint protocol + commit** ```bash git add dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/RouteHandlerTests.Impltests.cs porting.db git commit -m "test(batch16): resolve route slow-consumer recover status with evidence" ``` --- ### Task 5: Batch 16 Final Verification and Closure **Files:** - Modify: `porting.db` - Generate: `reports/current.md` (via report generation script) **Step 1: Run full verification** ```bash dotnet build dotnet/ dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --verbosity normal dotnet run --project tools/NatsNet.PortTracker -- batch show 16 --db porting.db ``` **Step 2: Ensure all Batch 16 items are `verified`, `complete`, or explicit `deferred` with reason** If anything is still `stub`, stop and resolve before completion. **Step 3: Complete batch** ```bash dotnet run --project tools/NatsNet.PortTracker -- batch complete 16 --db porting.db ``` **Step 4: Refresh report and final commit** ```bash ./reports/generate-report.sh git add porting.db reports/current.md reports/ git commit -m "chore(batch16): complete client core first-half verification cycle" ```