# Batch 17 (Client Core second half) Implementation Plan

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

**Goal:** Implement and verify Batch 17 (`server/client.go` second half) across 60 client-core features and 9 tracked tests using evidence-backed, anti-stub execution gates.

**Architecture:** Execute in three vertical feature groups (20 each) aligned to `client.go` functional seams: subscription/delivery, inbound/header/service import, and lifecycle/account/TLS/logging. Implement in `ClientConnection` partial files plus `ClientTypes` for `ClientInfo` behavior, then run tracked-test attempts with explicit dependency checks and defer reasoning where infra is still missing.

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

**Design doc:** `docs/plans/2026-02-27-batch-17-client-core-second-half-design.md`

---

I'm using `writeplan` to create the implementation plan.

## Batch Inputs

- Batch: `17` (`Client Core second half`)
- Depends on: `16`
- Features: `60`
- Tests: `9`
- Go source focus: `golang/nats-server/server/client.go` (line ~3057+)

Feature groups (max ~20 each):

- **Group A (20):** `477,478,479,480,481,482,483,484,485,486,487,488,489,490,491,492,493,494,495,496`
- **Group B (20):** `497,498,499,500,501,502,503,504,505,506,507,508,509,510,511,512,513,514,515,520`
- **Group C (20):** `521,522,534,535,537,540,541,542,543,544,545,546,547,548,553,565,566,567,568,569`

Tracked tests:

- `528,545,552,553,568,598,2053,2057,2901`

---

## MANDATORY VERIFICATION PROTOCOL

> **NON-NEGOTIABLE:** Every feature/test update in this batch must pass this protocol before status promotion.

### Per-Feature Verification Loop (REQUIRED for every feature ID)

1. Read tracker mapping and Go location:
   ```bash
   dotnet run --project tools/NatsNet.PortTracker -- feature show <FEATURE_ID> --db porting.db
   ```
2. Read the exact Go function in `golang/nats-server/server/client.go`.
3. Write minimal behavior-faithful C# implementation in mapped .NET file.
4. Build:
   ```bash
   dotnet build dotnet/
   ```
5. Run focused related tests (class/method filter):
   ```bash
   dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
     --filter "FullyQualifiedName~<RelatedClassOrMethod>" --verbosity normal
   ```
6. Confirm non-zero executed tests and `Failed: 0`.
7. Add feature ID to verified-candidate list only after green build + green related tests.

### Per-Test Verification Loop (REQUIRED for every tracked test ID)

1. Read mapping + dependencies:
   ```bash
   dotnet run --project tools/NatsNet.PortTracker -- test show <TEST_ID> --db porting.db
   ```
2. Read referenced Go test in `server/filestore_test.go`, `server/memstore_test.go`, or `server/server_test.go`.
3. Port behavior intent with real Arrange/Act/Assert.
4. Run the single mapped test:
   ```bash
   dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
     --filter "FullyQualifiedName~<MappedClass>.<MappedMethod>" --verbosity normal
   ```
5. Only mark `verified` when test executes and passes (`Passed: 1`, `Failed: 0`).

### Stub Detection Check (REQUIRED after every feature group and test task)

Run stub scans before any `complete`/`verified` updates:

```bash
# Feature code stubs/placeholders
grep -R -n -E "NotImplementedException|TODO|PLACEHOLDER" \
  dotnet/src/ZB.MOM.NatsNet.Server/ClientConnection*.cs \
  dotnet/src/ZB.MOM.NatsNet.Server/ClientTypes.cs

# Empty method bodies in touched feature files
grep -R -n -E "^[[:space:]]*(public|internal|private|protected)[^{;]*\\)[[:space:]]*\\{[[:space:]]*\\}$" \
  dotnet/src/ZB.MOM.NatsNet.Server/ClientConnection*.cs \
  dotnet/src/ZB.MOM.NatsNet.Server/ClientTypes.cs

# Test stubs/placeholders
grep -R -n -E "NotImplementedException|Assert\\.True\\(true\\)|Assert\\.Pass|ShouldBe\\(true\\);|// TODO|// PLACEHOLDER" \
  dotnet/tests/ZB.MOM.NatsNet.Server.Tests
```

Any new hit in touched files blocks promotion until fixed or deferred with explicit reason.

### Build Gate (REQUIRED after each feature group)

After every feature group task:

```bash
dotnet build dotnet/
```

Required: `0` build errors.

### Test Gate (REQUIRED before marking features `verified`)

Before any feature IDs move to `verified`, run and pass all related suites:

```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~ClientTests" --verbosity normal
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~ProtocolParserTests" --verbosity normal
```

If a group touches rate-limit logging or mapped server behaviors, also run:

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

Required: `Failed: 0` and non-zero executed tests for changed scenarios.

### Status Update Protocol (REQUIRED, evidence-backed)

1. Maximum **15 IDs per `feature batch-update` / `test batch-update` call**.
2. Allowed flow:
   - Features: `deferred -> stub -> complete -> verified` (or `deferred` with reason)
   - Tests: `deferred -> stub -> verified` (or `deferred` with reason)
3. Evidence required for each update chunk:
   - Go source review completed
   - Build output green
   - Related test output green
   - Stub scan clean
4. If audit disagrees, use explicit override reason.

### Checkpoint Protocol Between Tasks (REQUIRED)

After each major task (Group A, Group B, Group C, tests):

1. Full build:
   ```bash
   dotnet build dotnet/
   ```
2. Full unit test run:
   ```bash
   dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --verbosity normal
   ```
3. Confirm no new regressions.
4. Commit checkpoint before starting the next task.

---

## ANTI-STUB GUARDRAILS (NON-NEGOTIABLE)

### Forbidden Patterns

Do not introduce or keep these in Batch 17 feature/test code:

- `throw new NotImplementedException(...)`
- `// TODO` or `// PLACEHOLDER` in executable Batch 17 paths
- Empty method body placeholders (`{ }`)
- Trivial pass tests (`Assert.True(true)`, `Assert.Pass()`, literal-only assertions)
- Constant return placeholders for behavior-heavy methods (for example always `true`/`false` without Go-equivalent logic)
- Fake wrappers that ignore inputs and bypass Go behavior intent

### Hard Limits

- Max ~20 feature IDs per implementation task group (fixed at 20/20/20)
- Max 15 IDs per status-update command
- No status promotion without stub scan + build gate + test gate evidence
- No cross-group promotion; complete verification for one group before starting next
- Mandatory checkpoint commit between task groups

### If You Get Stuck

1. Stop work on the blocked item immediately.
2. Do **not** stub or fake-pass.
3. Set item back to `deferred` with exact blocker reason:
   ```bash
   dotnet run --project tools/NatsNet.PortTracker -- \
     feature update <ID> --status deferred --db porting.db \
     --override "blocked: <specific dependency/infra>"
   ```
   or
   ```bash
   dotnet run --project tools/NatsNet.PortTracker -- \
     test update <ID> --status deferred --db porting.db \
     --override "blocked: <specific dependency/infra>"
   ```
4. Continue with the next unblocked ID in the same task.

---

### Task 1: Preflight and Batch Start

**Files:**
- Modify: `porting.db`

**Step 1: Confirm dependency readiness**

```bash
dotnet run --project tools/NatsNet.PortTracker -- batch show 17 --db porting.db
dotnet run --project tools/NatsNet.PortTracker -- batch ready --db porting.db
```

Expected: Batch 17 is ready (Batch 16 complete).

**Step 2: Start batch**

```bash
dotnet run --project tools/NatsNet.PortTracker -- batch start 17 --db porting.db
```

**Step 3: Stage Group A to `stub` (<=15 IDs per command)**

```bash
dotnet run --project tools/NatsNet.PortTracker -- \
  feature batch-update --ids "477,478,479,480,481,482,483,484,485,486,487,488,489,490,491" \
  --set-status stub --db porting.db --execute

dotnet run --project tools/NatsNet.PortTracker -- \
  feature batch-update --ids "492,493,494,495,496" \
  --set-status stub --db porting.db --execute
```

**Step 4: Commit preflight**

```bash
git add porting.db
git commit -m "chore(batch17): start batch and stage group-a ids"
```

### Task 2: Group A Features (20) - Subscriptions, Delivery, Pub/Reply Permissions

**Feature IDs:** `477-496`

**Files:**
- Create: `dotnet/src/ZB.MOM.NatsNet.Server/ClientConnection.SubscriptionsAndDelivery.cs`
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/ClientConnection.cs`
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ClientConnectionStubFeaturesTests.cs`
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ClientTests.cs`

**Step 1: Write/extend failing tests for Group A behavior**

Focus on:
- shadow subscription additions
- unsubscribe + deny-sub checks
- route/leaf header generation
- delivery/pruning/reply tracking behavior
- publish allow checks and reply classifiers

**Step 2: 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~ClientTests" --verbosity normal
```

**Step 3: Implement Group A methods using per-feature verification loop**

**Step 4: Run mandatory stub detection + build gate + test gate**

Use protocol commands above.

**Step 5: Promote Group A feature statuses**

```bash
dotnet run --project tools/NatsNet.PortTracker -- \
  feature batch-update --ids "477,478,479,480,481,482,483,484,485,486,487,488,489,490,491" \
  --set-status complete --db porting.db --execute
dotnet run --project tools/NatsNet.PortTracker -- \
  feature batch-update --ids "492,493,494,495,496" \
  --set-status complete --db porting.db --execute

dotnet run --project tools/NatsNet.PortTracker -- \
  feature batch-update --ids "477,478,479,480,481,482,483,484,485,486,487,488,489,490,491" \
  --set-status verified --db porting.db --execute
dotnet run --project tools/NatsNet.PortTracker -- \
  feature batch-update --ids "492,493,494,495,496" \
  --set-status verified --db porting.db --execute
```

**Step 6: Checkpoint protocol + commit**

```bash
git add dotnet/src/ZB.MOM.NatsNet.Server/ClientConnection.SubscriptionsAndDelivery.cs \
        dotnet/src/ZB.MOM.NatsNet.Server/ClientConnection.cs \
        dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ClientConnectionStubFeaturesTests.cs \
        dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ClientTests.cs \
        porting.db
git commit -m "feat(batch17): port subscription and delivery client core features"
```

### Task 3: Group B Features (20) - Inbound Pipeline, Headers, Service Imports, Msg Results

**Feature IDs:** `497,498,499,500,501,502,503,504,505,506,507,508,509,510,511,512,513,514,515,520`

**Files:**
- Create: `dotnet/src/ZB.MOM.NatsNet.Server/ClientConnection.InboundAndHeaders.cs`
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/ClientConnection.cs`
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ClientConnectionStubFeaturesTests.cs`
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Protocol/ProtocolParserTests.cs`

**Step 1: Write/extend failing tests for Group B behavior**

Focus on:
- inbound client message processing and mapped subject selection
- gateway reply map + response service import setup
- header remove/set/get/slice helpers
- `processServiceImport`, route-target updates, and `processMsgResults`
- ping timer behavior (`processPingTimer`)

**Step 2: 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 3: Implement Group B methods using per-feature verification loop**

**Step 4: Run mandatory stub detection + build gate + test gate**

**Step 5: Promote Group B feature statuses (<=15 IDs/chunk)**

```bash
dotnet run --project tools/NatsNet.PortTracker -- \
  feature batch-update --ids "497,498,499,500,501,502,503,504,505,506,507,508,509,510,511" \
  --set-status complete --db porting.db --execute
dotnet run --project tools/NatsNet.PortTracker -- \
  feature batch-update --ids "512,513,514,515,520" \
  --set-status complete --db porting.db --execute

dotnet run --project tools/NatsNet.PortTracker -- \
  feature batch-update --ids "497,498,499,500,501,502,503,504,505,506,507,508,509,510,511" \
  --set-status verified --db porting.db --execute
dotnet run --project tools/NatsNet.PortTracker -- \
  feature batch-update --ids "512,513,514,515,520" \
  --set-status verified --db porting.db --execute
```

**Step 6: Checkpoint protocol + commit**

```bash
git add dotnet/src/ZB.MOM.NatsNet.Server/ClientConnection.InboundAndHeaders.cs \
        dotnet/src/ZB.MOM.NatsNet.Server/ClientConnection.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(batch17): port inbound, header, and service-import client features"
```

### Task 4: Group C Features (20) - Lifecycle, Account/Info, TLS, Rate-Limit Logging

**Feature IDs:** `521,522,534,535,537,540,541,542,543,544,545,546,547,548,553,565,566,567,568,569`

**Files:**
- Create: `dotnet/src/ZB.MOM.NatsNet.Server/ClientConnection.LifecycleAndTls.cs`
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/ClientConnection.cs`
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/ClientTypes.cs`
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ClientConnectionStubFeaturesTests.cs`
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/NatsServerTests.Impltests.cs`

**Step 1: Write/extend failing tests for Group C behavior**

Focus on:
- ping interval adjust + stale watcher + first ping timer
- account cache helpers and reload/reconnect paths
- client info account/service account enrichment
- TLS handshake wrappers and failure behavior
- rate-limited error/warn/debug logging wrappers

**Step 2: 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~NatsServerTests" --verbosity normal
```

**Step 3: Implement Group C methods using per-feature verification loop**

**Step 4: Run mandatory stub detection + build gate + test gate**

**Step 5: Promote Group C feature statuses (<=15 IDs/chunk)**

```bash
dotnet run --project tools/NatsNet.PortTracker -- \
  feature batch-update --ids "521,522,534,535,537,540,541,542,543,544,545,546,547,548,553" \
  --set-status complete --db porting.db --execute
dotnet run --project tools/NatsNet.PortTracker -- \
  feature batch-update --ids "565,566,567,568,569" \
  --set-status complete --db porting.db --execute

dotnet run --project tools/NatsNet.PortTracker -- \
  feature batch-update --ids "521,522,534,535,537,540,541,542,543,544,545,546,547,548,553" \
  --set-status verified --db porting.db --execute
dotnet run --project tools/NatsNet.PortTracker -- \
  feature batch-update --ids "565,566,567,568,569" \
  --set-status verified --db porting.db --execute
```

**Step 6: Checkpoint protocol + commit**

```bash
git add dotnet/src/ZB.MOM.NatsNet.Server/ClientConnection.LifecycleAndTls.cs \
        dotnet/src/ZB.MOM.NatsNet.Server/ClientConnection.cs \
        dotnet/src/ZB.MOM.NatsNet.Server/ClientTypes.cs \
        dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ClientConnectionStubFeaturesTests.cs \
        dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/NatsServerTests.Impltests.cs \
        porting.db
git commit -m "feat(batch17): port lifecycle, tls, and rate-limited logging features"
```

### Task 5: Tracked Tests (9) - Implement or Explicitly Defer With Reason

**Test IDs:** `528,545,552,553,568,598,2053,2057,2901`

**Files:**
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/JetStream/JetStreamFileStoreTests.cs`
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/JetStream/JetStreamMemoryStoreTests.cs`
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/NatsServerTests.Impltests.cs`
- Modify: `porting.db`

**Step 1: Stage all 9 tests to `stub` (single chunk <=15)**

```bash
dotnet run --project tools/NatsNet.PortTracker -- \
  test batch-update --ids "528,545,552,553,568,598,2053,2057,2901" \
  --set-status stub --db porting.db --execute
```

**Step 2: For each test, run dependency readiness check**

If dependencies remain deferred outside Batch 17, do not force-port; defer with explicit blocker.

**Step 3: Port only implementable tests using per-test verification loop**

Run each mapped test individually and confirm it executes/passes.

**Step 4: Stub scan + build + targeted JetStream/Server test gates**

```bash
dotnet build dotnet/
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~JetStreamFileStoreTests" --verbosity normal
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~JetStreamMemoryStoreTests" --verbosity normal
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~NatsServerTests" --verbosity normal
```

**Step 5: Update statuses**

- Verified chunk (only those with direct pass evidence, <=15 IDs).
- Deferred updates for blocked tests with explicit `--override` reason.

**Step 6: Checkpoint protocol + commit**

```bash
git add dotnet/tests/ZB.MOM.NatsNet.Server.Tests/JetStream/JetStreamFileStoreTests.cs \
        dotnet/tests/ZB.MOM.NatsNet.Server.Tests/JetStream/JetStreamMemoryStoreTests.cs \
        dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/NatsServerTests.Impltests.cs \
        porting.db
git commit -m "test(batch17): resolve tracked tests with pass evidence or explicit deferrals"
```

### Task 6: Final Batch 17 Verification and Closure

**Files:**
- Modify: `porting.db`
- Generate: `reports/current.md`

**Step 1: Full verification sweep**

```bash
dotnet build dotnet/
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --verbosity normal
dotnet run --project tools/NatsNet.PortTracker -- batch show 17 --db porting.db
```

**Step 2: Enforce no remaining Batch 17 stubs**

No Batch 17 feature/test should remain in `stub` status.

**Step 3: Complete batch**

```bash
dotnet run --project tools/NatsNet.PortTracker -- batch complete 17 --db porting.db
```

**Step 4: Update report + final commit**

```bash
./reports/generate-report.sh
git add porting.db reports/current.md reports/
git commit -m "chore(batch17): complete client core second-half verification cycle"
```

