# Batch 25 Gateways Implementation Plan

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

**Goal:** Port and verify Batch 25 (`Gateways`) by implementing 86 deferred gateway features from `server/gateway.go` and implementing/verifying all 59 mapped gateway-related tests as real behavioral tests.

**Architecture:** Implement gateway behavior in domain-focused partials for `NatsServer` and `ClientConnection`, with helper logic in `Gateway/GatewayHandler.cs` and state helpers in `GatewayTypes.cs`. Execute in five feature groups (19/18/17/16/16) and four test waves (15/16/18/10), each guarded by strict per-feature/per-test verification loops, anti-stub scans, and build/test gates before status promotion.

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

**Design doc:** `docs/plans/2026-02-27-batch-25-gateways-design.md`

---

## Batch 25 Scope

- Batch ID: `25`
- Name: `Gateways`
- Dependencies: `19`, `23`
- Go source: `golang/nats-server/server/gateway.go`
- Features: `86`
- Tests: `59`

Reference commands:

```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- batch show 25 --db porting.db
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- batch list --db porting.db
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- report summary --db porting.db
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- batch ready --db porting.db
```

If `dotnet` is on `PATH`, equivalent commands may use `dotnet` directly.

Primary production files:

- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/Gateway/GatewayTypes.cs`
- Create: `dotnet/src/ZB.MOM.NatsNet.Server/Gateway/GatewayHandler.cs`
- Create: `dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Gateways.ConfigAndStartup.cs`
- Create: `dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Gateways.ConnectionsAndGossip.cs`
- Create: `dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Gateways.Interest.cs`
- Create: `dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Gateways.ReplyMap.cs`
- Create: `dotnet/src/ZB.MOM.NatsNet.Server/ClientConnection.Gateways.Protocol.cs`
- Create: `dotnet/src/ZB.MOM.NatsNet.Server/ClientConnection.Gateways.Messages.cs`
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Init.cs`
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Lifecycle.cs`
- Modify (as needed): `dotnet/src/ZB.MOM.NatsNet.Server/Protocol/ProtocolParser.cs`

Mapped test files:

- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/GatewayHandlerTests.Impltests.cs`
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/LeafNodeHandlerTests.Impltests.cs`
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/MonitoringHandlerTests.Impltests.cs`
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/JetStreamEngineTests.Impltests.cs`
- Create/Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/JetStreamSuperClusterTests.Impltests.cs`
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/ConcurrencyTests1.Impltests.cs`
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/ConcurrencyTests2.Impltests.cs`
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/ConfigReloaderTests.Impltests.cs`
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/NatsServerTests.Impltests.cs`

---

## MANDATORY VERIFICATION PROTOCOL

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

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

1. Read tracker metadata and Go source before coding:

```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- feature show <feature_id> --db porting.db
# then open golang/nats-server/server/gateway.go at go_line_number..(go_line_number + go_line_count)
```

2. Write/adjust C# implementation for that specific feature.
3. Build immediately after each feature (or tightly coupled feature pair):

```bash
/usr/local/share/dotnet/dotnet build dotnet/
```

4. Run the smallest related test filter immediately after the build:

```bash
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
  --filter "FullyQualifiedName~GatewayHandlerTests|FullyQualifiedName~ProtocolParserTests|FullyQualifiedName~ClientTests|FullyQualifiedName~NatsServerTests"
```

5. Record evidence for the feature ID: Go lines read, files touched, build result, test command, pass/fail summary.
6. If any command is red, fix before starting the next feature ID.

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

1. Read Go test source from tracker metadata:

```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- test show <test_id> --db porting.db
```

2. Port behavior (not syntax) into mapped `.Impltests.cs` method.
3. Run the single method filter and confirm discovery:

```bash
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
  --filter "FullyQualifiedName~<ClassName>.<MethodName>" --verbosity normal
```

4. Confirm the run reports `Passed: 1` and `Failed: 0`.
5. Add the test ID to verification candidates only after a green individual run.

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

Run before any status promotion:

```bash
# Forbidden markers in mapped production + test files
grep -R -n -E "(NotImplementedException|TODO|PLACEHOLDER|Assert\\.True\\(true\\)|ShouldContain\\(\"Should\"\\))" \
  --include="Gateway*.cs" \
  --include="NatsServer.Gateways*.cs" \
  --include="ClientConnection.Gateways*.cs" \
  --include="NatsServer.Init.cs" \
  --include="NatsServer.Lifecycle.cs" \
  --include="GatewayHandlerTests.Impltests.cs" \
  --include="LeafNodeHandlerTests.Impltests.cs" \
  --include="MonitoringHandlerTests.Impltests.cs" \
  --include="JetStreamEngineTests.Impltests.cs" \
  --include="JetStreamSuperClusterTests.Impltests.cs" \
  --include="ConcurrencyTests1.Impltests.cs" \
  --include="ConcurrencyTests2.Impltests.cs" \
  --include="ConfigReloaderTests.Impltests.cs" \
  --include="NatsServerTests.Impltests.cs" \
  dotnet/src/ZB.MOM.NatsNet.Server \
  dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog

# Empty method bodies in mapped production files
grep -R -n -E "^[[:space:]]*(public|internal|private|protected)[^{;=]*\\)[[:space:]]*\\{[[:space:]]*\\}$" \
  --include="Gateway*.cs" \
  --include="NatsServer.Gateways*.cs" \
  --include="ClientConnection.Gateways*.cs" \
  dotnet/src/ZB.MOM.NatsNet.Server
```

Any hit must be fixed or deferred with a reason before status promotion.

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

```bash
/usr/local/share/dotnet/dotnet build dotnet/
```

`Build succeeded` is mandatory before any `stub -> complete` feature update.

### Test Gate (REQUIRED before any `complete -> verified` feature promotion)

All Batch 25 mapped/related tests must pass:

```bash
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~GatewayHandlerTests"
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~LeafNodeHandlerTests.LeafNodeAndGatewaysSingleMsgPerQueueGroup_ShouldSucceed|FullyQualifiedName~LeafNodeHandlerTests.LeafNodeQueueGroupWeightCorrectOnConnectionCloseInSuperCluster_ShouldSucceed"
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~MonitoringHandlerTests.MonitorGatewayURLsUpdated_ShouldSucceed|FullyQualifiedName~MonitoringHandlerTests.MonitorGatewayzAccounts_ShouldSucceed"
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~ConcurrencyTests1.NoRaceGatewayNoMissingReplies_ShouldSucceed|FullyQualifiedName~ConcurrencyTests2.NoRaceConnectionObjectReleased_ShouldSucceed"
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~ConfigReloaderTests.ConfigReloadClusterAdvertise_ShouldSucceed|FullyQualifiedName~NatsServerTests.ReconnectErrorReports_ShouldSucceed"
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~JetStreamEngineTests.JetStreamStreamConfigClone_ShouldSucceed|FullyQualifiedName~JetStreamSuperClusterTests.JetStreamSuperClusterInterestOnlyMode_ShouldSucceed"
```

No Batch 25 feature is eligible for `verified` until this gate is green.

### Status Update Protocol (REQUIRED)

- Never include more than `15` IDs in any `feature batch-update` or `test batch-update`.
- Required progression:
  - `deferred -> stub` at work start
  - `stub -> complete` only after clean stub scan + build gate
  - `complete -> verified` only after full Test Gate
- Evidence is required for every update chunk:
  - build summary,
  - test summary,
  - stub-scan summary,
  - exact IDs being promoted.

Command templates:

```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
  feature batch-update --ids "<max 15 ids>" --set-status <stub|complete|verified> --db porting.db --execute

/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
  test batch-update --ids "<max 15 ids>" --set-status <stub|complete|verified> --db porting.db --execute
```

### Checkpoint Protocol Between Tasks (REQUIRED)

After each task, before starting the next task:

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

git add dotnet/src/ZB.MOM.NatsNet.Server dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog porting.db
git commit -m "<batch25 checkpoint message>"
```

Do not continue if checkpoint gates fail.

### If You Get Stuck (REQUIRED)

1. Stop on the blocked feature/test ID.
2. Remove partial placeholder code (no TODO stubs left behind).
3. Mark blocked item as `deferred` with specific reason:

```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
  feature update <id> --status deferred --override "blocked: <specific reason>" --db porting.db

/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
  test update <id> --status deferred --override "blocked: <specific reason>" --db porting.db
```

4. Move to the next unblocked ID.
5. Never ship or verify a stub to keep momentum.

---

## ANTI-STUB GUARDRAILS (NON-NEGOTIABLE)

### Forbidden Patterns

The following patterns are forbidden in Batch 25 production and test code:

- `throw new NotImplementedException()`
- Empty method body `{ }` for mapped methods
- `// TODO` and `// PLACEHOLDER` in mapped code paths
- Placeholder return defaults for non-trivial methods (`return false;`, `return 0;`, `return string.Empty;`, `return null;`) without behavioral logic
- `Assert.True(true)` or similar tautological assertions
- `"...".ShouldContain("Should")` placeholder assertion pattern in `ImplBacklog` tests
- Tests that do not execute production code under test

### Hard Limits

- Maximum `20` features per feature task
- Maximum `15` IDs per status update command
- Maximum `1` feature group active at a time
- Zero unresolved stub-scan matches before status promotion
- Mandatory checkpoint gate (full build + full tests + commit) between tasks

---

## Feature Groups (<=20 IDs each)

### Group 1 (19 IDs): Gateway bootstrap, option validation, startup, solicitation

IDs:

`1263,1264,1265,1266,1268,1269,1270,1271,1272,1273,1275,1276,1277,1278,1279,1280,1281,1282,1283`

Focus:

- Solicit delay controls and gateway mode helpers
- Gateway option validation and hash helpers
- `NewGateway`, startup accept loop, solicitation/reconnect bootstrap
- Early inbound existence and gateway creation path

### Group 2 (18 IDs): CONNECT/INFO handshake, gossip, and remote config propagation

IDs:

`1284,1285,1286,1287,1288,1289,1290,1291,1292,1293,1294,1295,1296,1297,1298,1299,1300,1301`

Focus:

- `SendGatewayConnect`, `ProcessGatewayConnect`, `ProcessGatewayInfo`
- Gateway-to-route gossip/config propagation
- Outbound/inbound count and remote lookup helpers
- Initial gateway connection-attempt tracking

### Group 3 (17 IDs): Gateway URL/state bookkeeping and connection registry ordering

IDs:

`1302,1303,1304,1305,1306,1307,1308,1309,1310,1311,1312,1313,1315,1316,1317,1318,1319`

Focus:

- GatewayCfg URL mutation/accessors and TLS hostname cache
- Cluster URL add/remove and async INFO broadcast
- Gateway URL/name lookup
- Inbound/outbound registration and ordered outbound list maintenance

### Group 4 (16 IDs): Interest mode transitions and outbound send decisions

IDs:

`1320,1321,1323,1324,1325,1326,1327,1328,1329,1330,1331,1333,1334,1335,1336,1337`

Focus:

- Inbound connection enumeration and address helpers
- Account/RSub/RUnsub protocol handlers
- Account switch-to-interest-only logic
- Routed-reply detection/prefix logic and send decision path

### Group 5 (16 IDs): No-interest handling, reply-map routing, inbound message pipeline

IDs:

`1338,1339,1340,1341,1342,1343,1344,1345,1346,1347,1348,1349,1350,1351,1352,1353`

Focus:

- Account/subject no-interest handling and A- emission
- Route hash table helpers and routed reply subject extraction
- `HandleGatewayReply`, `ProcessInboundGatewayMsg`, all-subs receive start/complete
- Reply-map tracking and expiration worker

---

## Test Waves

### Wave 1 (15 IDs): Basic connect/listen/auth/TLS/reconnect scenarios

IDs:

`600,601,605,608,609,610,611,612,613,615,616,617,618,620,621`

### Wave 2 (16 IDs): Interest propagation, queue subs, and service import baseline

IDs:

`624,627,630,631,632,634,638,639,640,644,645,647,650,651,652,653`

### Wave 3 (18 IDs): Interest-mode edge cases, TLS reload/discovery, slow consumer/no-race gateway paths

IDs:

`660,661,662,663,664,667,669,670,672,673,674,675,676,677,679,680,681,687`

### Wave 4 (10 IDs): Cross-module integration tests (JetStream/Leaf/Monitor/NoRace/Reload/Server)

IDs:

`1426,1715,1962,1963,2127,2131,2376,2490,2747,2899`

---

## Task 1: Preflight and Dependency Gate

**Files:**

- Read: `docs/standards/dotnet-standards.md`
- Read: `docs/plans/2026-02-27-batch-25-gateways-design.md`
- Read: `golang/nats-server/server/gateway.go`

**Step 1: Confirm batch metadata**

```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- batch show 25 --db porting.db
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- batch list --db porting.db
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- report summary --db porting.db
```

**Step 2: Verify dependency readiness**

```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- batch ready --db porting.db
```

Expected: Batch `25` appears only after dependencies `19` and `23` are complete.

**Step 3: Start batch only if ready**

```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- batch start 25 --db porting.db
```

**Step 4: Baseline build/test gate**

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

**Step 5: Checkpoint commit**

```bash
git add porting.db
git commit -m "chore(batch25): start gateways batch"
```

---

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

**Files:**

- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/Gateway/GatewayTypes.cs`
- Create: `dotnet/src/ZB.MOM.NatsNet.Server/Gateway/GatewayHandler.cs`
- Create/Modify: `dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Gateways.ConfigAndStartup.cs`
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Init.cs`

**Step 1: Move Group 1 to `stub` in <=15 chunks**

```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
  feature batch-update --ids "1263,1264,1265,1266,1268,1269,1270,1271,1272,1273,1275,1276,1277,1278,1279" --set-status stub --db porting.db --execute
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
  feature batch-update --ids "1280,1281,1282,1283" --set-status stub --db porting.db --execute
```

**Step 2: Execute per-feature verification loop for all Group 1 IDs**

**Step 3: Run stub detection check + build gate + targeted tests**

```bash
# run stub detection commands from protocol section
/usr/local/share/dotnet/dotnet build dotnet/
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~GatewayHandlerTests|FullyQualifiedName~NatsServerTests"
```

**Step 4: Move Group 1 to `complete` in <=15 chunks**

```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
  feature batch-update --ids "1263,1264,1265,1266,1268,1269,1270,1271,1272,1273,1275,1276,1277,1278,1279" --set-status complete --db porting.db --execute
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
  feature batch-update --ids "1280,1281,1282,1283" --set-status complete --db porting.db --execute
```

**Step 5: Run checkpoint protocol and commit**

```bash
git commit -m "feat(batch25): implement gateway bootstrap and solicitation"
```

---

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

**Files:**

- Create/Modify: `dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Gateways.ConnectionsAndGossip.cs`
- Create/Modify: `dotnet/src/ZB.MOM.NatsNet.Server/ClientConnection.Gateways.Protocol.cs`
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/Protocol/ProtocolParser.cs`

**Step 1: Move Group 2 to `stub` in <=15 chunks**

```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
  feature batch-update --ids "1284,1285,1286,1287,1288,1289,1290,1291,1292,1293,1294,1295,1296,1297,1298" --set-status stub --db porting.db --execute
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
  feature batch-update --ids "1299,1300,1301" --set-status stub --db porting.db --execute
```

**Step 2: Execute per-feature verification loop for all Group 2 IDs**

**Step 3: Run stub detection check + build gate + targeted tests**

```bash
# run stub detection commands from protocol section
/usr/local/share/dotnet/dotnet build dotnet/
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~GatewayHandlerTests|FullyQualifiedName~ClientTests"
```

**Step 4: Move Group 2 to `complete` in <=15 chunks**

```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
  feature batch-update --ids "1284,1285,1286,1287,1288,1289,1290,1291,1292,1293,1294,1295,1296,1297,1298" --set-status complete --db porting.db --execute
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
  feature batch-update --ids "1299,1300,1301" --set-status complete --db porting.db --execute
```

**Step 5: Run checkpoint protocol and commit**

```bash
git commit -m "feat(batch25): implement gateway handshake and gossip"
```

---

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

**Files:**

- Create/Modify: `dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Gateways.ConnectionsAndGossip.cs`
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Lifecycle.cs`
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/Gateway/GatewayTypes.cs`

**Step 1: Move Group 3 to `stub` in <=15 chunks**

```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
  feature batch-update --ids "1302,1303,1304,1305,1306,1307,1308,1309,1310,1311,1312,1313,1315,1316,1317" --set-status stub --db porting.db --execute
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
  feature batch-update --ids "1318,1319" --set-status stub --db porting.db --execute
```

**Step 2: Execute per-feature verification loop for all Group 3 IDs**

**Step 3: Run stub detection check + build gate + targeted tests**

```bash
# run stub detection commands from protocol section
/usr/local/share/dotnet/dotnet build dotnet/
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~GatewayHandlerTests|FullyQualifiedName~MonitoringHandlerTests"
```

**Step 4: Move Group 3 to `complete` in <=15 chunks**

```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
  feature batch-update --ids "1302,1303,1304,1305,1306,1307,1308,1309,1310,1311,1312,1313,1315,1316,1317" --set-status complete --db porting.db --execute
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
  feature batch-update --ids "1318,1319" --set-status complete --db porting.db --execute
```

**Step 5: Run checkpoint protocol and commit**

```bash
git commit -m "feat(batch25): implement gateway URL and registry bookkeeping"
```

---

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

**Files:**

- Create/Modify: `dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Gateways.Interest.cs`
- Create/Modify: `dotnet/src/ZB.MOM.NatsNet.Server/ClientConnection.Gateways.Protocol.cs`
- Create/Modify: `dotnet/src/ZB.MOM.NatsNet.Server/ClientConnection.Gateways.Messages.cs`
- Create/Modify: `dotnet/src/ZB.MOM.NatsNet.Server/Gateway/GatewayHandler.cs`

**Step 1: Move Group 4 to `stub` in <=15 chunks**

```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
  feature batch-update --ids "1320,1321,1323,1324,1325,1326,1327,1328,1329,1330,1331,1333,1334,1335,1336" --set-status stub --db porting.db --execute
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
  feature batch-update --ids "1337" --set-status stub --db porting.db --execute
```

**Step 2: Execute per-feature verification loop for all Group 4 IDs**

**Step 3: Run stub detection check + build gate + targeted tests**

```bash
# run stub detection commands from protocol section
/usr/local/share/dotnet/dotnet build dotnet/
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~GatewayHandlerTests|FullyQualifiedName~LeafNodeHandlerTests|FullyQualifiedName~ConcurrencyTests1"
```

**Step 4: Move Group 4 to `complete` in <=15 chunks**

```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
  feature batch-update --ids "1320,1321,1323,1324,1325,1326,1327,1328,1329,1330,1331,1333,1334,1335,1336" --set-status complete --db porting.db --execute
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
  feature batch-update --ids "1337" --set-status complete --db porting.db --execute
```

**Step 5: Run checkpoint protocol and commit**

```bash
git commit -m "feat(batch25): implement gateway interest and outbound send logic"
```

---

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

**Files:**

- Create/Modify: `dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Gateways.ReplyMap.cs`
- Create/Modify: `dotnet/src/ZB.MOM.NatsNet.Server/ClientConnection.Gateways.Messages.cs`
- Create/Modify: `dotnet/src/ZB.MOM.NatsNet.Server/Gateway/GatewayHandler.cs`
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Lifecycle.cs`

**Step 1: Move Group 5 to `stub` in <=15 chunks**

```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
  feature batch-update --ids "1338,1339,1340,1341,1342,1343,1344,1345,1346,1347,1348,1349,1350,1351,1352" --set-status stub --db porting.db --execute
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
  feature batch-update --ids "1353" --set-status stub --db porting.db --execute
```

**Step 2: Execute per-feature verification loop for all Group 5 IDs**

**Step 3: Run stub detection check + build gate + targeted tests**

```bash
# run stub detection commands from protocol section
/usr/local/share/dotnet/dotnet build dotnet/
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~GatewayHandlerTests|FullyQualifiedName~ConcurrencyTests1|FullyQualifiedName~ConcurrencyTests2|FullyQualifiedName~NatsServerTests"
```

**Step 4: Move Group 5 to `complete` in <=15 chunks**

```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
  feature batch-update --ids "1338,1339,1340,1341,1342,1343,1344,1345,1346,1347,1348,1349,1350,1351,1352" --set-status complete --db porting.db --execute
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
  feature batch-update --ids "1353" --set-status complete --db porting.db --execute
```

**Step 5: Run checkpoint protocol and commit**

```bash
git commit -m "feat(batch25): implement gateway reply map and inbound message pipeline"
```

---

## Task 7: Port and Verify Test Wave 1 (15 IDs)

**Files:**

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

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

```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
  test batch-update --ids "600,601,605,608,609,610,611,612,613,615,616,617,618,620,621" --set-status stub --db porting.db --execute
```

**Step 2: Execute per-test verification loop for each ID**

**Step 3: Run class-level gate and stub scan**

```bash
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~GatewayHandlerTests"
# run stub detection commands from protocol section
```

**Step 4: Move Wave 1 tests to `complete`**

```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
  test batch-update --ids "600,601,605,608,609,610,611,612,613,615,616,617,618,620,621" --set-status complete --db porting.db --execute
```

**Step 5: Run checkpoint protocol and commit**

```bash
git commit -m "test(batch25): port gateway connect and tls baseline tests"
```

---

## Task 8: Port and Verify Test Wave 2 (16 IDs)

**Files:**

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

**Step 1: Move Wave 2 tests to `stub` in <=15 chunks**

```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
  test batch-update --ids "624,627,630,631,632,634,638,639,640,644,645,647,650,651,652" --set-status stub --db porting.db --execute
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
  test batch-update --ids "653" --set-status stub --db porting.db --execute
```

**Step 2: Execute per-test verification loop for each ID**

**Step 3: Run class-level gate and stub scan**

```bash
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~GatewayHandlerTests"
# run stub detection commands from protocol section
```

**Step 4: Move Wave 2 tests to `complete` in <=15 chunks**

```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
  test batch-update --ids "624,627,630,631,632,634,638,639,640,644,645,647,650,651,652" --set-status complete --db porting.db --execute
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
  test batch-update --ids "653" --set-status complete --db porting.db --execute
```

**Step 5: Run checkpoint protocol and commit**

```bash
git commit -m "test(batch25): port gateway interest and service-import tests"
```

---

## Task 9: Port and Verify Test Wave 3 (18 IDs)

**Files:**

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

**Step 1: Move Wave 3 tests to `stub` in <=15 chunks**

```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
  test batch-update --ids "660,661,662,663,664,667,669,670,672,673,674,675,676,677,679" --set-status stub --db porting.db --execute
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
  test batch-update --ids "680,681,687" --set-status stub --db porting.db --execute
```

**Step 2: Execute per-test verification loop for each ID**

**Step 3: Run class-level gate and stub scan**

```bash
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~GatewayHandlerTests"
# run stub detection commands from protocol section
```

**Step 4: Move Wave 3 tests to `complete` in <=15 chunks**

```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
  test batch-update --ids "660,661,662,663,664,667,669,670,672,673,674,675,676,677,679" --set-status complete --db porting.db --execute
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
  test batch-update --ids "680,681,687" --set-status complete --db porting.db --execute
```

**Step 5: Run checkpoint protocol and commit**

```bash
git commit -m "test(batch25): port gateway edge, reload, and slow-consumer tests"
```

---

## Task 10: Port and Verify Test Wave 4 (10 IDs, cross-module)

**Files:**

- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/LeafNodeHandlerTests.Impltests.cs`
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/MonitoringHandlerTests.Impltests.cs`
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/JetStreamEngineTests.Impltests.cs`
- Create/Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/JetStreamSuperClusterTests.Impltests.cs`
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/ConcurrencyTests1.Impltests.cs`
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/ConcurrencyTests2.Impltests.cs`
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/ConfigReloaderTests.Impltests.cs`
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/NatsServerTests.Impltests.cs`

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

```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
  test batch-update --ids "1426,1715,1962,1963,2127,2131,2376,2490,2747,2899" --set-status stub --db porting.db --execute
```

**Step 2: Execute per-test verification loop for each ID**

**Step 3: Run targeted class gates and stub scan**

```bash
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~LeafNodeHandlerTests|FullyQualifiedName~MonitoringHandlerTests|FullyQualifiedName~JetStreamEngineTests|FullyQualifiedName~JetStreamSuperClusterTests|FullyQualifiedName~ConcurrencyTests1|FullyQualifiedName~ConcurrencyTests2|FullyQualifiedName~ConfigReloaderTests|FullyQualifiedName~NatsServerTests"
# run stub detection commands from protocol section
```

**Step 4: Move Wave 4 tests to `complete`**

```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
  test batch-update --ids "1426,1715,1962,1963,2127,2131,2376,2490,2747,2899" --set-status complete --db porting.db --execute
```

**Step 5: Run checkpoint protocol and commit**

```bash
git commit -m "test(batch25): port cross-module gateway integration tests"
```

---

## Task 11: Verification Gate and Promote to `verified`

**Files:**

- Modify: `porting.db`

**Step 1: Run full Batch 25 test gate**

```bash
# run all commands from the Test Gate subsection in MANDATORY VERIFICATION PROTOCOL
```

**Step 2: Promote all 59 tests to `verified` in <=15 chunks**

```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
  test batch-update --ids "600,601,605,608,609,610,611,612,613,615,616,617,618,620,621" --set-status verified --db porting.db --execute
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
  test batch-update --ids "624,627,630,631,632,634,638,639,640,644,645,647,650,651,652" --set-status verified --db porting.db --execute
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
  test batch-update --ids "653,660,661,662,663,664,667,669,670,672,673,674,675,676,677" --set-status verified --db porting.db --execute
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
  test batch-update --ids "679,680,681,687,1426,1715,1962,1963,2127,2131,2376,2490,2747,2899" --set-status verified --db porting.db --execute
```

**Step 3: Promote all 86 features to `verified` in <=15 chunks**

```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
  feature batch-update --ids "1263,1264,1265,1266,1268,1269,1270,1271,1272,1273,1275,1276,1277,1278,1279" --set-status verified --db porting.db --execute
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
  feature batch-update --ids "1280,1281,1282,1283,1284,1285,1286,1287,1288,1289,1290,1291,1292,1293,1294" --set-status verified --db porting.db --execute
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
  feature batch-update --ids "1295,1296,1297,1298,1299,1300,1301,1302,1303,1304,1305,1306,1307,1308,1309" --set-status verified --db porting.db --execute
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
  feature batch-update --ids "1310,1311,1312,1313,1315,1316,1317,1318,1319,1320,1321,1323,1324,1325,1326" --set-status verified --db porting.db --execute
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
  feature batch-update --ids "1327,1328,1329,1330,1331,1333,1334,1335,1336,1337,1338,1339,1340,1341,1342" --set-status verified --db porting.db --execute
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
  feature batch-update --ids "1343,1344,1345,1346,1347,1348,1349,1350,1351,1352,1353" --set-status verified --db porting.db --execute
```

**Step 4: Run checkpoint protocol and commit**

```bash
git commit -m "feat(batch25): verify gateway features and tests"
```

---

## Task 12: Batch Closure and Reporting

**Files:**

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

**Step 1: Final build/test sweep**

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

**Step 2: Final Batch 25 stub audit**

```bash
# rerun full stub detection commands from MANDATORY VERIFICATION PROTOCOL
```

**Step 3: Verify batch closure**

```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- batch show 25 --db porting.db
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- batch complete 25 --db porting.db
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- report summary --db porting.db
```

**Step 4: Generate report and final 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/
git commit -m "feat(batch25): complete gateways implementation and verification"
```
