# Batch 21 Events + MsgTrace Implementation Plan

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

**Goal:** Implement and verify Batch 21 (`Events + MsgTrace`) by porting 118 deferred features from `server/events.go` and `server/msgtrace.go`, and by replacing 9 mapped deferred tests with real behavior-valid tests.

**Architecture:** Implement runtime behavior in focused partial/runtime files (`NatsServer.Events*.cs`, `ClientConnection.MsgTrace.cs`, `MsgTraceRuntime.cs`) while reusing existing DTO/type models in `EventTypes.cs` and `MsgTraceTypes.cs`. Execute in six feature groups (max 20 IDs each), keep IDs in `stub -> complete` during implementation, then move to `verified` only after full related test gate passes. Treat infra-blocked tests/features as explicitly deferred rather than stubbing.

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

**Design doc:** `docs/plans/2026-02-27-batch-21-events-msgtrace-design.md`

---

## Batch 21 Scope

- Batch ID: `21`
- Name: `Events + MsgTrace`
- Dependencies: batches `18`, `19`
- Go source files:
  - `golang/nats-server/server/events.go`
  - `golang/nats-server/server/msgtrace.go`
- Features: `118`
- Tests: `9`

Primary source files to modify/create:

- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/NatsServerTypes.cs`
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/ClientTypes.cs`
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/Accounts/Account.cs`
- Create/Modify: `dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Events.cs`
- Create/Modify: `dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Events.System.cs`
- Create/Modify: `dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Events.Admin.cs`
- Create/Modify: `dotnet/src/ZB.MOM.NatsNet.Server/ClientConnection.MsgTrace.cs`
- Create/Modify: `dotnet/src/ZB.MOM.NatsNet.Server/MessageTrace/MsgTraceRuntime.cs`

Primary mapped test files:

- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/EventsHandlerTests.Impltests.cs`
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/MessageTracerTests.Impltests.cs`
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/ConcurrencyTests1.Impltests.cs`

---

## MANDATORY VERIFICATION PROTOCOL

> **NON-NEGOTIABLE:** Every Batch 21 feature and mapped test must follow this protocol.

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

1. Read feature metadata and Go behavior before coding:
   ```bash
   dotnet run --project tools/NatsNet.PortTracker -- feature show <feature_id> --db porting.db
   ```
2. Read the corresponding Go method body in `events.go` or `msgtrace.go`.
3. Implement only the mapped behavior in the target C# file (no placeholder code).
4. Build immediately:
   ```bash
   dotnet build dotnet/
   ```
5. Run the smallest related tests immediately:
   ```bash
   dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~EventsHandlerTests|FullyQualifiedName~MessageTracerTests|FullyQualifiedName~ConcurrencyTests1|FullyQualifiedName~ServerTests|FullyQualifiedName~AccountTests|FullyQualifiedName~ClientConnectionStubFeaturesTests"
   ```
6. Only after green build + related tests: keep the feature ID in the current `complete-candidate` set.
7. If red: fix before moving to the next feature ID.

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

Run on touched files before any status promotion:

```bash
# Forbidden placeholder/stub markers
grep -R -n -E "(NotImplementedException|TODO|PLACEHOLDER|Assert\.True\(true\)|throw new Exception\(\"TODO\"\))" \
  dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Events*.cs \
  dotnet/src/ZB.MOM.NatsNet.Server/ClientConnection.MsgTrace.cs \
  dotnet/src/ZB.MOM.NatsNet.Server/MessageTrace/MsgTraceRuntime.cs \
  dotnet/src/ZB.MOM.NatsNet.Server/NatsServerTypes.cs \
  dotnet/src/ZB.MOM.NatsNet.Server/ClientTypes.cs \
  dotnet/src/ZB.MOM.NatsNet.Server/Accounts/Account.cs \
  dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/EventsHandlerTests.Impltests.cs \
  dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/MessageTracerTests.Impltests.cs \
  dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/ConcurrencyTests1.Impltests.cs

# Empty body detector in touched source files
grep -R -n -E "^[[:space:]]*(public|internal|private|protected)[^{;=]*\)[[:space:]]*\{[[:space:]]*\}$" \
  dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Events*.cs \
  dotnet/src/ZB.MOM.NatsNet.Server/ClientConnection.MsgTrace.cs \
  dotnet/src/ZB.MOM.NatsNet.Server/MessageTrace/MsgTraceRuntime.cs \
  dotnet/src/ZB.MOM.NatsNet.Server/NatsServerTypes.cs \
  dotnet/src/ZB.MOM.NatsNet.Server/ClientTypes.cs \
  dotnet/src/ZB.MOM.NatsNet.Server/Accounts/Account.cs
```

Any new hit must be fixed or explicitly deferred. No exceptions.

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

```bash
dotnet build dotnet/
```

`Build succeeded` is required before any feature group IDs move to `complete`.

### Test Gate (REQUIRED before setting any Batch 21 feature to `verified`)

All related tests must pass first:

```bash
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~ZB.MOM.NatsNet.Server.Tests.ImplBacklog.EventsHandlerTests"
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~ZB.MOM.NatsNet.Server.Tests.ImplBacklog.MessageTracerTests"
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~ZB.MOM.NatsNet.Server.Tests.ImplBacklog.ConcurrencyTests1"
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~ZB.MOM.NatsNet.Server.Tests.ServerTests"
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~ZB.MOM.NatsNet.Server.Tests.Accounts.AccountTests"
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~ZB.MOM.NatsNet.Server.Tests.ClientConnectionStubFeaturesTests"
```

No Batch 21 feature ID can be `verified` while mapped tests are failing, undiscovered, or still placeholder-based.

### Status Update Protocol (REQUIRED)

- Maximum `15` IDs per `feature batch-update` or `test batch-update` command.
- Required state progression:
  - `deferred/not_started -> stub` when active work starts.
  - `stub -> complete` only after feature-group build gate + stub scan.
  - `complete -> verified` only after full test gate.
- Evidence required before each status-update chunk:
  - latest successful `dotnet build` summary,
  - latest successful related test summary,
  - clean stub scan for touched files,
  - explicit list of IDs in that chunk.

### Checkpoint Protocol Between Tasks (REQUIRED)

Between every major task (feature group or test wave):

1. Full build:
   ```bash
   dotnet build dotnet/
   ```
2. Full unit tests:
   ```bash
   dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/
   ```
3. Commit checkpoint:
   ```bash
   git add dotnet/src/ZB.MOM.NatsNet.Server dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog porting.db
   git commit -m "<task-specific message>"
   ```

---

## ANTI-STUB GUARDRAILS (NON-NEGOTIABLE)

### Forbidden Patterns

- `throw new NotImplementedException()` in Batch 21 mapped methods.
- Empty method bodies for mapped features.
- `// TODO`, `// PLACEHOLDER`, or fake temporary logic in mapped behavior.
- Placeholder pass tests (`Assert.True(true)`, string/self assertions not tied to behavior).
- Default-return stubs (`return null`, `return 0`, `return false`, `return string.Empty`) where Go behavior is non-trivial.
- Tests that do not call production Batch 21 code paths.

### Hard Limits

- Maximum `~20` features per group task.
- Maximum `15` IDs per status-update command.
- Only one feature group in active status transition at a time.
- No feature promoted to `verified` before the mapped test gate is green.
- Mandatory checkpoint (full build + full tests + commit) between tasks.

### If You Get Stuck (REQUIRED)

1. Stop working on the blocked ID immediately.
2. Remove partial placeholder logic for that ID.
3. Keep or set the blocked item to `deferred` with explicit reason:
   ```bash
   dotnet run --project tools/NatsNet.PortTracker -- feature update <id> --status deferred --override "blocked: <specific reason>" --db porting.db
   dotnet run --project tools/NatsNet.PortTracker -- test update <id> --status deferred --override "blocked: <specific reason>" --db porting.db
   ```
4. Continue with next unblocked ID.
5. Never introduce stubs to maintain pace.

---

## Feature Groups (Max ~20 IDs)

### Group 1 (20 IDs): Capability helpers + internal message loop foundations

`854,855,856,857,858,859,860,861,862,863,864,865,866,868,869,870,871,872,873,874`

### Group 2 (20 IDs): Event-state lifecycle + statsz/timer/hash/node initialization

`875,876,877,878,879,880,881,882,883,884,885,886,887,888,889,890,891,892,893,894`

### Group 3 (20 IDs): System import wiring + remote server/account update paths

`895,897,898,899,900,901,902,903,904,905,907,908,909,910,911,912,913,914,917,918`

### Group 4 (20 IDs): Account connection advisories + sys-subscribe and latency/reply flows

`919,920,921,923,925,926,927,928,929,930,931,932,933,934,935,936,937,938,939,940`

### Group 5 (20 IDs): Admin/debug/OCSP event paths + MsgTrace type/converter bridge

`941,942,943,944,945,946,947,948,949,950,2406,2407,2408,2409,2410,2411,2412,2413,2420,2421`

### Group 6 (18 IDs): MsgTrace runtime behaviors (conn names, headers, sampling, event emission)

`2422,2423,2424,2425,2426,2427,2428,2429,2430,2431,2432,2433,2434,2435,2436,2437,2438,2439`

---

## Test Waves (9 IDs)

### Wave 1 (6 IDs): events_test.go mapped behaviors in `EventsHandlerTests`

`303,304,305,319,334,343`

Target methods to add/replace:
- `SysSubscribeRace_ShouldSucceed`
- `SystemAccountInternalSubscriptions_ShouldSucceed`
- `SystemAccountConnectionUpdatesStopAfterNoLocal_ShouldSucceed`
- `SystemAccountWithBadRemoteLatencyUpdate_ShouldSucceed`
- `ConnectionUpdatesTimerProperlySet_ShouldSucceed`
- `ClusterSetupMsgs_ShouldSucceed`

### Wave 2 (3 IDs): msgtrace/norace mapped behaviors

`2329,2330,2412`

Target methods to add/replace:
- `MsgTraceConnName_ShouldSucceed`
- `MsgTraceGenHeaderMap_ShouldSucceed`
- `NoRaceJetStreamLastSubjSeqAndFilestoreCompact_ShouldSucceed`

---

## Task 1: Preflight, Dependency Validation, Batch Start

**Files:**
- Read: `docs/standards/dotnet-standards.md`
- Read: `docs/plans/2026-02-27-batch-21-events-msgtrace-design.md`
- Read: `golang/nats-server/server/events.go`
- Read: `golang/nats-server/server/msgtrace.go`

**Step 1: Validate batch status and dependency readiness**

```bash
dotnet run --project tools/NatsNet.PortTracker -- batch list --db porting.db
dotnet run --project tools/NatsNet.PortTracker -- batch show 21 --db porting.db
dotnet run --project tools/NatsNet.PortTracker -- report summary --db porting.db
```

**Step 2: Start batch when dependencies are satisfied**

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

**Step 3: Capture baseline build/tests**

```bash
dotnet build dotnet/
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/
```

**Step 4: Commit checkpoint**

```bash
git add porting.db
git commit -m "chore(batch21): start events-msgtrace batch"
```

---

## Task 2: Implement Feature Group 1 (20 IDs)

**Files:**
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/NatsServerTypes.cs`
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/ClientTypes.cs`
- Create/Modify: `dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Events.cs`

**Step 1: Move IDs to `stub` (max 15 per command)**

```bash
dotnet run --project tools/NatsNet.PortTracker -- feature batch-update --ids "854,855,856,857,858,859,860,861,862,863,864,865,866,868,869" --set-status stub --db porting.db --execute
dotnet run --project tools/NatsNet.PortTracker -- feature batch-update --ids "870,871,872,873,874" --set-status stub --db porting.db --execute
```

**Step 2: Execute Per-Feature Verification Loop for all 20 IDs**

**Step 3: Run required stub scan + build gate**

**Step 4: Move IDs to `complete` (max 15 per command)**

```bash
dotnet run --project tools/NatsNet.PortTracker -- feature batch-update --ids "854,855,856,857,858,859,860,861,862,863,864,865,866,868,869" --set-status complete --db porting.db --execute
dotnet run --project tools/NatsNet.PortTracker -- feature batch-update --ids "870,871,872,873,874" --set-status complete --db porting.db --execute
```

**Step 5: Run Checkpoint Protocol**

---

## Task 3: Implement Feature Group 2 (20 IDs)

**Files:**
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Events.cs`
- Create/Modify: `dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Events.System.cs`

**Step 1: Move IDs to `stub`**

```bash
dotnet run --project tools/NatsNet.PortTracker -- feature batch-update --ids "875,876,877,878,879,880,881,882,883,884,885,886,887,888,889" --set-status stub --db porting.db --execute
dotnet run --project tools/NatsNet.PortTracker -- feature batch-update --ids "890,891,892,893,894" --set-status stub --db porting.db --execute
```

**Step 2: Execute Per-Feature Verification Loop for all 20 IDs**

**Step 3: Run required stub scan + build gate**

**Step 4: Move IDs to `complete`**

```bash
dotnet run --project tools/NatsNet.PortTracker -- feature batch-update --ids "875,876,877,878,879,880,881,882,883,884,885,886,887,888,889" --set-status complete --db porting.db --execute
dotnet run --project tools/NatsNet.PortTracker -- feature batch-update --ids "890,891,892,893,894" --set-status complete --db porting.db --execute
```

**Step 5: Run Checkpoint Protocol**

---

## Task 4: Implement Feature Group 3 (20 IDs)

**Files:**
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Events.System.cs`
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Events.cs`

**Step 1: Move IDs to `stub`**

```bash
dotnet run --project tools/NatsNet.PortTracker -- feature batch-update --ids "895,897,898,899,900,901,902,903,904,905,907,908,909,910,911" --set-status stub --db porting.db --execute
dotnet run --project tools/NatsNet.PortTracker -- feature batch-update --ids "912,913,914,917,918" --set-status stub --db porting.db --execute
```

**Step 2: Execute Per-Feature Verification Loop for all 20 IDs**

**Step 3: Run required stub scan + build gate**

**Step 4: Move IDs to `complete`**

```bash
dotnet run --project tools/NatsNet.PortTracker -- feature batch-update --ids "895,897,898,899,900,901,902,903,904,905,907,908,909,910,911" --set-status complete --db porting.db --execute
dotnet run --project tools/NatsNet.PortTracker -- feature batch-update --ids "912,913,914,917,918" --set-status complete --db porting.db --execute
```

**Step 5: Run Checkpoint Protocol**

---

## Task 5: Implement Feature Group 4 (20 IDs)

**Files:**
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Events.System.cs`
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/Accounts/Account.cs`

**Step 1: Move IDs to `stub`**

```bash
dotnet run --project tools/NatsNet.PortTracker -- feature batch-update --ids "919,920,921,923,925,926,927,928,929,930,931,932,933,934,935" --set-status stub --db porting.db --execute
dotnet run --project tools/NatsNet.PortTracker -- feature batch-update --ids "936,937,938,939,940" --set-status stub --db porting.db --execute
```

**Step 2: Execute Per-Feature Verification Loop for all 20 IDs**

**Step 3: Run required stub scan + build gate**

**Step 4: Move IDs to `complete`**

```bash
dotnet run --project tools/NatsNet.PortTracker -- feature batch-update --ids "919,920,921,923,925,926,927,928,929,930,931,932,933,934,935" --set-status complete --db porting.db --execute
dotnet run --project tools/NatsNet.PortTracker -- feature batch-update --ids "936,937,938,939,940" --set-status complete --db porting.db --execute
```

**Step 5: Run Checkpoint Protocol**

---

## Task 6: Implement Feature Group 5 (20 IDs)

**Files:**
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Events.Admin.cs`
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/MessageTrace/MsgTraceTypes.cs`
- Create/Modify: `dotnet/src/ZB.MOM.NatsNet.Server/MessageTrace/MsgTraceRuntime.cs`

**Step 1: Move IDs to `stub`**

```bash
dotnet run --project tools/NatsNet.PortTracker -- feature batch-update --ids "941,942,943,944,945,946,947,948,949,950,2406,2407,2408,2409,2410" --set-status stub --db porting.db --execute
dotnet run --project tools/NatsNet.PortTracker -- feature batch-update --ids "2411,2412,2413,2420,2421" --set-status stub --db porting.db --execute
```

**Step 2: Execute Per-Feature Verification Loop for all 20 IDs**

**Step 3: Run required stub scan + build gate**

**Step 4: Move IDs to `complete`**

```bash
dotnet run --project tools/NatsNet.PortTracker -- feature batch-update --ids "941,942,943,944,945,946,947,948,949,950,2406,2407,2408,2409,2410" --set-status complete --db porting.db --execute
dotnet run --project tools/NatsNet.PortTracker -- feature batch-update --ids "2411,2412,2413,2420,2421" --set-status complete --db porting.db --execute
```

**Step 5: Run Checkpoint Protocol**

---

## Task 7: Implement Feature Group 6 (18 IDs)

**Files:**
- Create/Modify: `dotnet/src/ZB.MOM.NatsNet.Server/ClientConnection.MsgTrace.cs`
- Create/Modify: `dotnet/src/ZB.MOM.NatsNet.Server/MessageTrace/MsgTraceRuntime.cs`

**Step 1: Move IDs to `stub`**

```bash
dotnet run --project tools/NatsNet.PortTracker -- feature batch-update --ids "2422,2423,2424,2425,2426,2427,2428,2429,2430,2431,2432,2433,2434,2435,2436" --set-status stub --db porting.db --execute
dotnet run --project tools/NatsNet.PortTracker -- feature batch-update --ids "2437,2438,2439" --set-status stub --db porting.db --execute
```

**Step 2: Execute Per-Feature Verification Loop for all 18 IDs**

**Step 3: Run required stub scan + build gate**

**Step 4: Move IDs to `complete`**

```bash
dotnet run --project tools/NatsNet.PortTracker -- feature batch-update --ids "2422,2423,2424,2425,2426,2427,2428,2429,2430,2431,2432,2433,2434,2435,2436" --set-status complete --db porting.db --execute
dotnet run --project tools/NatsNet.PortTracker -- feature batch-update --ids "2437,2438,2439" --set-status complete --db porting.db --execute
```

**Step 5: Run Checkpoint Protocol**

---

## Task 8: Port/Verify Test Wave 1 (Events, 6 IDs)

**Files:**
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/EventsHandlerTests.Impltests.cs`

**Step 1: Move Wave 1 tests to `stub`**

```bash
dotnet run --project tools/NatsNet.PortTracker -- test batch-update --ids "303,304,305,319,334,343" --set-status stub --db porting.db --execute
```

**Step 2: Per-test loop for each ID**

For each test ID:

```bash
dotnet run --project tools/NatsNet.PortTracker -- test show <test_id> --db porting.db
# Read corresponding Go test block in golang/nats-server/server/events_test.go
```

Implement real Arrange/Act/Assert logic against Batch 21 production paths.

**Step 3: Run class-level test gate**

```bash
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~ZB.MOM.NatsNet.Server.Tests.ImplBacklog.EventsHandlerTests"
```

**Step 4: Run stub scan on touched tests + set `verified` for passing IDs**

```bash
dotnet run --project tools/NatsNet.PortTracker -- test batch-update --ids "303,304,305,319,334,343" --set-status verified --db porting.db --execute
```

If any test is blocked, keep deferred with explicit reason and only verify proven IDs.

**Step 5: Run Checkpoint Protocol**

---

## Task 9: Port/Verify Test Wave 2 (MsgTrace + NoRace, 3 IDs)

**Files:**
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/MessageTracerTests.Impltests.cs`
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/ConcurrencyTests1.Impltests.cs`

**Step 1: Move Wave 2 tests to `stub`**

```bash
dotnet run --project tools/NatsNet.PortTracker -- test batch-update --ids "2329,2330,2412" --set-status stub --db porting.db --execute
```

**Step 2: Per-test loop for each ID**

Use `test show <id>` and corresponding Go tests:
- `golang/nats-server/server/msgtrace_test.go`
- `golang/nats-server/server/norace_1_test.go`

**Step 3: Run class-level test gates**

```bash
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~ZB.MOM.NatsNet.Server.Tests.ImplBacklog.MessageTracerTests"
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~ZB.MOM.NatsNet.Server.Tests.ImplBacklog.ConcurrencyTests1"
```

**Step 4: Promote passing tests to `verified`**

```bash
dotnet run --project tools/NatsNet.PortTracker -- test batch-update --ids "2329,2330,2412" --set-status verified --db porting.db --execute
```

If blocked, defer with explicit reason.

**Step 5: Run Checkpoint Protocol**

---

## Task 10: Final Feature Verification, Batch Closure, and Reporting

**Files:**
- Modify: `porting.db`
- Optional update: `reports/current.md` (via report generation script)

**Step 1: Execute full Batch 21 test gate**

Run all commands from the mandatory Test Gate section.

**Step 2: Promote complete feature IDs to `verified` in max-15 chunks**

Use the same per-group chunking used for `stub`/`complete` transitions, but with `--set-status verified`.

Example (Group 1):

```bash
dotnet run --project tools/NatsNet.PortTracker -- feature batch-update --ids "854,855,856,857,858,859,860,861,862,863,864,865,866,868,869" --set-status verified --db porting.db --execute
dotnet run --project tools/NatsNet.PortTracker -- feature batch-update --ids "870,871,872,873,874" --set-status verified --db porting.db --execute
```

Repeat for Groups 2-6.

**Step 3: Confirm all Batch 21 items are in terminal statuses**

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

**Step 4: Complete the batch**

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

**Step 5: Generate updated report and final checkpoint commit**

```bash
./reports/generate-report.sh
git add dotnet/src/ZB.MOM.NatsNet.Server dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog porting.db reports/current.md
git commit -m "feat(batch21): implement and verify events and msgtrace"
```

---

## Notes

- If `dotnet` is not on PATH, use `/usr/local/share/dotnet/dotnet` for all commands.
- Do not edit unrelated backlog tests while executing this plan.
- Do not mark `verified` without captured evidence for build, tests, and stub scan.
