diff --git a/.claude/worktrees/agent-a0bc1fd2 b/.claude/worktrees/agent-a0bc1fd2
new file mode 160000
index 0000000..41ea272
--- /dev/null
+++ b/.claude/worktrees/agent-a0bc1fd2
@@ -0,0 +1 @@
+Subproject commit 41ea272c8adc5693089237d833e7a53fb29b9d2d
diff --git a/.claude/worktrees/agent-a24b291a b/.claude/worktrees/agent-a24b291a
new file mode 160000
index 0000000..e846cb6
--- /dev/null
+++ b/.claude/worktrees/agent-a24b291a
@@ -0,0 +1 @@
+Subproject commit e846cb664a979dda12ad3e8f7da51fa4fe7a5e2f
diff --git a/.claude/worktrees/agent-a2ba16fc b/.claude/worktrees/agent-a2ba16fc
new file mode 160000
index 0000000..a841b55
--- /dev/null
+++ b/.claude/worktrees/agent-a2ba16fc
@@ -0,0 +1 @@
+Subproject commit a841b553f2c2d58f266c08a2452d6864d5b7f42f
diff --git a/.claude/worktrees/agent-a3c77b78 b/.claude/worktrees/agent-a3c77b78
new file mode 160000
index 0000000..41ea272
--- /dev/null
+++ b/.claude/worktrees/agent-a3c77b78
@@ -0,0 +1 @@
+Subproject commit 41ea272c8adc5693089237d833e7a53fb29b9d2d
diff --git a/.claude/worktrees/agent-a59c3695 b/.claude/worktrees/agent-a59c3695
new file mode 160000
index 0000000..41ea272
--- /dev/null
+++ b/.claude/worktrees/agent-a59c3695
@@ -0,0 +1 @@
+Subproject commit 41ea272c8adc5693089237d833e7a53fb29b9d2d
diff --git a/.claude/worktrees/agent-a5ce7551 b/.claude/worktrees/agent-a5ce7551
new file mode 160000
index 0000000..96e395a
--- /dev/null
+++ b/.claude/worktrees/agent-a5ce7551
@@ -0,0 +1 @@
+Subproject commit 96e395a113b9c9a8edd5a019f0c38f5b03f39ae5
diff --git a/.claude/worktrees/agent-a76e2054 b/.claude/worktrees/agent-a76e2054
new file mode 160000
index 0000000..41ea272
--- /dev/null
+++ b/.claude/worktrees/agent-a76e2054
@@ -0,0 +1 @@
+Subproject commit 41ea272c8adc5693089237d833e7a53fb29b9d2d
diff --git a/.claude/worktrees/agent-a830a417 b/.claude/worktrees/agent-a830a417
new file mode 160000
index 0000000..8db4fcc
--- /dev/null
+++ b/.claude/worktrees/agent-a830a417
@@ -0,0 +1 @@
+Subproject commit 8db4fccc95b0576d63435e238a32f86847358288
diff --git a/.claude/worktrees/agent-a8f732c0 b/.claude/worktrees/agent-a8f732c0
new file mode 160000
index 0000000..41ea272
--- /dev/null
+++ b/.claude/worktrees/agent-a8f732c0
@@ -0,0 +1 @@
+Subproject commit 41ea272c8adc5693089237d833e7a53fb29b9d2d
diff --git a/.claude/worktrees/agent-ab176f1b b/.claude/worktrees/agent-ab176f1b
new file mode 160000
index 0000000..4e63820
--- /dev/null
+++ b/.claude/worktrees/agent-ab176f1b
@@ -0,0 +1 @@
+Subproject commit 4e63820e7a3320128f1f17a34075f712d516078c
diff --git a/.claude/worktrees/agent-acd0ba80 b/.claude/worktrees/agent-acd0ba80
new file mode 160000
index 0000000..41ea272
--- /dev/null
+++ b/.claude/worktrees/agent-acd0ba80
@@ -0,0 +1 @@
+Subproject commit 41ea272c8adc5693089237d833e7a53fb29b9d2d
diff --git a/.claude/worktrees/agent-ae174143 b/.claude/worktrees/agent-ae174143
new file mode 160000
index 0000000..41ea272
--- /dev/null
+++ b/.claude/worktrees/agent-ae174143
@@ -0,0 +1 @@
+Subproject commit 41ea272c8adc5693089237d833e7a53fb29b9d2d
diff --git a/.claude/worktrees/agent-aea55702 b/.claude/worktrees/agent-aea55702
new file mode 160000
index 0000000..bebff91
--- /dev/null
+++ b/.claude/worktrees/agent-aea55702
@@ -0,0 +1 @@
+Subproject commit bebff9168a41ea124e57670a26c15f6eaed83be2
diff --git a/.claude/worktrees/agent-afa3d16c b/.claude/worktrees/agent-afa3d16c
new file mode 160000
index 0000000..41ea272
--- /dev/null
+++ b/.claude/worktrees/agent-afa3d16c
@@ -0,0 +1 @@
+Subproject commit 41ea272c8adc5693089237d833e7a53fb29b9d2d
diff --git a/docs/plans/2026-03-01-deferred-integration-tests-plan.md b/docs/plans/2026-03-01-deferred-integration-tests-plan.md
new file mode 100644
index 0000000..f83b0fc
--- /dev/null
+++ b/docs/plans/2026-03-01-deferred-integration-tests-plan.md
@@ -0,0 +1,1056 @@
+# Deferred Integration Tests Implementation Plan
+
+> **For Claude:** REQUIRED SUB-SKILL: Use superpowers-extended-cc:executing-plans to implement this plan task-by-task.
+
+**Goal:** Port 884 deferred integration tests from Go to C#, with a shared test harness, so they compile and skip gracefully until the .NET server can boot.
+
+**Architecture:** Wave 1 builds the test harness (Batch 48). Wave 2 launches 11 parallel Sonnet agents in isolated worktrees to port all 884 tests (Batches 49-59). Each agent reads Go source, creates .NET test files using the harness, and updates porting.db. Post-merge reconciliation promotes all tests to verified.
+
+**Tech Stack:** .NET 10, xUnit 2.9.3, Shouldly, NSubstitute, NATS.Client.Core 2.7.2, Xunit.SkippableFact
+
+---
+
+## Execution Model
+
+### Wave 1: Harness (Sequential)
+
+Batch 48 creates the test infrastructure. Must merge to `main` before Wave 2 starts.
+
+### Wave 2: Test Batches (Parallel)
+
+All 11 test batches (49-59) launch simultaneously as Sonnet agents with `isolation: "worktree"`. Each agent works independently — no shared files between batches.
+
+### Merge Strategy
+
+1. Merge each completed worktree branch to `main` sequentially
+2. Resolve conflicts in `reports/current.md` by keeping `--ours`
+3. After all merges, run post-merge reconciliation (Batch 59+ / Task 13)
+
+---
+
+## Shared Standards (All Batches)
+
+### .NET Standards
+- .NET 10, C# latest, nullable enabled, file-scoped namespaces
+- xUnit 2.9.3, Shouldly assertions, NSubstitute mocking
+- PascalCase public members, `_camelCase` private fields
+- `[SkippableFact]`/`[SkippableTheory]` from Xunit.SkippableFact for runtime skip
+- Test naming: `[Method]_[Scenario]_[Expected]` (e.g., `StreamCreate_ValidConfig_Succeeds`)
+
+### Go-to-C# Translation
+
+| Go Pattern | C# Pattern |
+|-----------|------------|
+| `TestFoo(t *testing.T)` | `public void Foo_ShouldSucceed()` or `public async Task Foo_ShouldSucceed()` |
+| `t.Fatal("msg")` | `Assert.Fail("msg")` or Shouldly assertion |
+| `t.Errorf("fmt", args)` | `result.ShouldBe(expected)` |
+| `defer s.Shutdown()` | `using var server = TestServerHelper.RunBasicJetStreamServer(Output)` |
+| `natsConnect(t, url)` | `NatsTestClient.Connect(url)` |
+| `checkFor(t, 10*time.Second, ...)` | `CheckHelper.CheckFor(TimeSpan.FromSeconds(10), ...)` |
+| `c := createJetStreamClusterExplicit(t, "R3", 3)` | `using var c = TestCluster.CreateJetStreamCluster(3, "R3")` |
+| `//go:build !race` | `[Trait("Category", "NoRace")]` |
+| `t.Skip("reason")` | `Skip.If(true, "reason")` |
+
+### Agent Prompt Wrapper
+
+Every batch prompt below should be wrapped with these execution rules:
+
+```
+EXECUTION RULES:
+1. You are working in an isolated git worktree. Do NOT modify porting.db.
+2. All files go under dotnet/tests/ZB.MOM.NatsNet.Server.IntegrationTests/
+3. Build: dotnet build dotnet/tests/ZB.MOM.NatsNet.Server.IntegrationTests/
+4. After build succeeds, run: dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --no-build
+ to confirm no regressions in existing unit tests.
+5. Commit all changes with message: "test(batch{N}): port {description}"
+6. Do NOT push. Do NOT modify files outside the integration test project.
+```
+
+---
+
+## Task 1: Batch 48 — Test Harness Infrastructure
+
+**Batch**: 48
+**Tests**: 0 (foundation only)
+**Blocked by**: Nothing
+**Blocks**: All test batches (49-59)
+
+### Files to Create
+
+| File | Purpose |
+|------|---------|
+| `Helpers/TestServerHelper.cs` | Server lifecycle (RunServer, CanBoot, GetFreePort, CreateTempDir) |
+| `Helpers/TestCluster.cs` | Multi-server cluster (CreateJetStreamCluster, WaitOnLeader, etc.) |
+| `Helpers/TestSuperCluster.cs` | Multi-cluster with gateways |
+| `Helpers/NatsTestClient.cs` | NATS.Client.Core wrapper for test connections |
+| `Helpers/CheckHelper.cs` | Retry/polling (CheckFor, CheckClusterFormed) |
+| `Helpers/ConfigHelper.cs` | Config templates and temp file management |
+| `Helpers/IntegrationTestBase.cs` | Abstract base class with Skip guard |
+
+### Files to Modify
+
+| File | Change |
+|------|--------|
+| `ZB.MOM.NatsNet.Server.IntegrationTests.csproj` | Add `Xunit.SkippableFact` package |
+
+### Go Reference Files
+
+| File | What to Extract |
+|------|----------------|
+| `golang/nats-server/server/jetstream_helpers_test.go` | cluster struct, createJetStreamCluster*, supercluster, config templates |
+| `golang/nats-server/server/test_helper_test.go` | RunServer, natsConnect, checkFor, GetFreePort |
+
+### Agent Prompt
+
+```
+BATCH 48: Test Harness Infrastructure
+
+You are building shared test infrastructure for 884 integration tests. No tests in this batch — just the helpers.
+
+TARGET PROJECT: dotnet/tests/ZB.MOM.NatsNet.Server.IntegrationTests/
+
+STEP 1: Add Xunit.SkippableFact package to the .csproj:
+
+
+STEP 2: Read these Go files for reference patterns:
+ - golang/nats-server/server/jetstream_helpers_test.go (cluster, supercluster, config templates)
+ - golang/nats-server/server/test_helper_test.go (RunServer, natsConnect, checkFor)
+
+STEP 3: Create these 7 files under Helpers/:
+
+=== Helpers/TestServerHelper.cs ===
+Namespace: ZB.MOM.NatsNet.Server.IntegrationTests.Helpers
+Internal static class. Methods:
+- CanBoot(): Try to create a NatsServer instance, return true/false. Catch all exceptions.
+- RunServer(ServerOptions opts): Create NatsServer, call Start(), return (server, opts).
+- RunBasicJetStreamServer(ITestOutputHelper output): Create ServerOptions with JetStream enabled + temp store dir, call RunServer.
+- RunServerWithConfig(string configFile): Parse config, create ServerOptions, call RunServer.
+- GetFreePort(): Use TcpListener on port 0 to find available port.
+- CreateTempDir(string prefix): Path.Combine(Path.GetTempPath(), prefix + Guid.NewGuid().ToString("N")[..8]), create directory, return path.
+
+=== Helpers/TestCluster.cs ===
+Namespace: ZB.MOM.NatsNet.Server.IntegrationTests.Helpers
+Internal sealed class, implements IDisposable.
+Mirrors Go `cluster` struct from jetstream_helpers_test.go.
+Properties: NatsServer[] Servers, ServerOptions[] Options, string Name.
+Static factory methods:
+- CreateJetStreamCluster(int numServers, string name): Allocate ports, create configs with routes, start all servers.
+- CreateJetStreamClusterWithTemplate(string template, int numServers, string name): Use template string with port substitution.
+Wait helpers:
+- WaitOnClusterReady(): CheckHelper.CheckFor polling until all servers see correct route count.
+- WaitOnLeader(): Poll until one server reports as leader.
+- WaitOnStreamLeader(account, stream): Poll for stream leader.
+- WaitOnConsumerLeader(account, stream, consumer): Poll for consumer leader.
+Accessors:
+- StreamLeader, ConsumerLeader, Leader, RandomServer, ServerByName.
+Lifecycle:
+- StopAll, RestartAll, Dispose (shutdown all).
+
+=== Helpers/TestSuperCluster.cs ===
+Namespace: ZB.MOM.NatsNet.Server.IntegrationTests.Helpers
+Internal sealed class, implements IDisposable.
+Properties: TestCluster[] Clusters.
+Static factory:
+- CreateJetStreamSuperCluster(int numPerCluster, int numClusters): Create multiple clusters with gateway configs.
+Methods: Leader, RandomServer, ServerByName, WaitOnLeader, WaitOnStreamLeader, ClusterForName, Dispose.
+
+=== Helpers/NatsTestClient.cs ===
+Namespace: ZB.MOM.NatsNet.Server.IntegrationTests.Helpers
+Internal static class. Uses NATS.Client.Core (already in project).
+- Connect(string url, NatsOpts? opts = null): Create NatsConnection with test defaults.
+- ConnectToServer(NatsServer server, NatsOpts? opts = null): Build URL from server's port, call Connect.
+
+=== Helpers/CheckHelper.cs ===
+Namespace: ZB.MOM.NatsNet.Server.IntegrationTests.Helpers
+Internal static class.
+- CheckFor(TimeSpan timeout, TimeSpan interval, Func check): Loop with Thread.Sleep(interval) until check returns null or timeout expires. Throw last exception on timeout.
+- CheckClusterFormed(params NatsServer[] servers): CheckFor verifying route counts match expected.
+- CheckLeafNodeConnectedCount(NatsServer server, int expected): CheckFor verifying leaf node count.
+
+=== Helpers/ConfigHelper.cs ===
+Namespace: ZB.MOM.NatsNet.Server.IntegrationTests.Helpers
+Internal static class.
+- const string JsClusterTemplate: Mirrors Go jsClusterTempl from jetstream_helpers_test.go. Template with %STORE_DIR%, %PORT%, %CLUSTER_PORT%, %ROUTES%, etc.
+- const string JsSuperClusterTemplate: Mirrors Go jsSuperClusterTempl with gateway config.
+- CreateConfigFile(string content): Write to temp file, return path.
+
+=== Helpers/IntegrationTestBase.cs ===
+Namespace: ZB.MOM.NatsNet.Server.IntegrationTests
+[Trait("Category", "Integration")]
+Public abstract class, implements IDisposable.
+Constructor takes ITestOutputHelper, calls Skip.If(!TestServerHelper.CanBoot(), "Server cannot boot").
+Protected Output property.
+Virtual Dispose().
+
+STEP 4: Build: dotnet build dotnet/tests/ZB.MOM.NatsNet.Server.IntegrationTests/
+STEP 5: Run existing unit tests: dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --no-build -c Debug
+STEP 6: Commit: "test(batch48): add integration test harness infrastructure"
+```
+
+---
+
+## Task 2: Batch 49 — JetStream Core (126 tests)
+
+**Batch**: 49
+**Tests**: 126 (70 + 56)
+**Blocked by**: Batch 48 (Task 1)
+
+### Go Source Files
+
+| File | Test Count |
+|------|-----------|
+| `golang/nats-server/server/jetstream_test.go` | 70 |
+| `golang/nats-server/server/jetstream_consumer_test.go` | 56 |
+
+### .NET Target Files
+
+| File | Source |
+|------|--------|
+| `JetStream/JetStreamTests.cs` | jetstream_test.go |
+| `JetStream/JetStreamConsumerTests.cs` | jetstream_consumer_test.go |
+
+### Test IDs (porting.db)
+
+**jetstream_test.go** (70): 1479,1503,1506,1507,1509,1524,1533,1534,1541,1542,1543,1560,1566,1568,1569,1570,1571,1574,1577,1578,1579,1580,1588,1611,1622,1626,1658,1676,1679,1680,1685,1687,1688,1691,1698,1705,1706,1707,1712,1714,1717,1718,1729,1730,1736,1737,1738,1742,1746,1753,1754,1755,1756,1758,1759,1760,1761,1765,1766,1768,1769,1770,1771,1775,1778,1779,1781,1783,1784,1785
+
+**jetstream_consumer_test.go** (56): 1229,1234,1238,1245,1246,1247,1254,1255,1256,1257,1258,1269,1270,1271,1272,1275,1276,1288,1292,1294,1296,1300,1301,1305,1307,1309,1310,1322,1323,1324,1327,1329,1331,1335,1337,1338,1345,1351,1354,1360,1361,1362,1363,1366,1367,1368,1369,1371,1372,1373,1374,1375,1376,1377,1378,1380
+
+### Agent Prompt
+
+```
+BATCH 49: JetStream Core Integration Tests (126 tests)
+
+Port 126 integration tests from Go to C#. These test JetStream stream/consumer operations.
+
+GO SOURCE FILES (read these first):
+ - golang/nats-server/server/jetstream_test.go (70 tests)
+ - golang/nats-server/server/jetstream_consumer_test.go (56 tests)
+
+.NET TARGET FILES (create these):
+ - dotnet/tests/ZB.MOM.NatsNet.Server.IntegrationTests/JetStream/JetStreamTests.cs
+ - dotnet/tests/ZB.MOM.NatsNet.Server.IntegrationTests/JetStream/JetStreamConsumerTests.cs
+
+HARNESS APIs AVAILABLE (under Helpers/):
+ - TestServerHelper.RunBasicJetStreamServer(Output) — single JS server
+ - TestServerHelper.CanBoot() — for Skip guard
+ - NatsTestClient.Connect(url) / ConnectToServer(server)
+ - CheckHelper.CheckFor(timeout, interval, check)
+ - ConfigHelper.CreateConfigFile(content)
+ - IntegrationTestBase — base class with Skip guard
+
+PORTING PATTERN:
+Each test class inherits IntegrationTestBase and uses [SkippableFact] or [SkippableTheory].
+Each test method ports the full Go test logic. Use Shouldly for assertions.
+Use `using var server = TestServerHelper.RunBasicJetStreamServer(Output);` for server lifecycle.
+Use `using var nc = NatsTestClient.ConnectToServer(server);` for client connections.
+
+CLASS STRUCTURE:
+ JetStreamTests : IntegrationTestBase — 70 test methods from jetstream_test.go
+ JetStreamConsumerTests : IntegrationTestBase — 56 test methods from jetstream_consumer_test.go
+
+NAMING: Convert Go TestFoo to Foo_ShouldSucceed (or appropriate _Scenario_Expected suffix).
+
+TEST IDS — jetstream_test.go (70):
+1479,1503,1506,1507,1509,1524,1533,1534,1541,1542,1543,1560,1566,1568,1569,1570,1571,1574,1577,1578,1579,1580,1588,1611,1622,1626,1658,1676,1679,1680,1685,1687,1688,1691,1698,1705,1706,1707,1712,1714,1717,1718,1729,1730,1736,1737,1738,1742,1746,1753,1754,1755,1756,1758,1759,1760,1761,1765,1766,1768,1769,1770,1771,1775,1778,1779,1781,1783,1784,1785
+
+TEST IDS — jetstream_consumer_test.go (56):
+1229,1234,1238,1245,1246,1247,1254,1255,1256,1257,1258,1269,1270,1271,1272,1275,1276,1288,1292,1294,1296,1300,1301,1305,1307,1309,1310,1322,1323,1324,1327,1329,1331,1335,1337,1338,1345,1351,1354,1360,1361,1362,1363,1366,1367,1368,1369,1371,1372,1373,1374,1375,1376,1377,1378,1380
+
+BUILD: dotnet build dotnet/tests/ZB.MOM.NatsNet.Server.IntegrationTests/
+VERIFY: dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --no-build -c Debug
+COMMIT: "test(batch49): port 126 JetStream core integration tests"
+```
+
+---
+
+## Task 3: Batch 50 — JetStream Cluster 1 (118 tests)
+
+**Batch**: 50
+**Tests**: 118
+**Blocked by**: Batch 48 (Task 1)
+
+### Go Source Files
+
+| File | Test Count |
+|------|-----------|
+| `golang/nats-server/server/jetstream_cluster_1_test.go` | 118 |
+
+### .NET Target Files
+
+| File | Source |
+|------|--------|
+| `JetStream/JetStreamCluster1Tests.cs` | jetstream_cluster_1_test.go |
+
+### Test IDs (porting.db)
+
+**jetstream_cluster_1_test.go** (118): 758,759,760,762,764,766,768,770,772,774,776,778,780,782,784,786,788,790,792,794,796,798,800,802,804,806,808,810,812,814,816,818,820,822,824,826,828,830,832,834,836,838,840,842,844,846,847,848,849,850,851,852,853,854,855,856,857,858,859,860,861,862,863,864,865,866,867,868,869,870,871,872,873,874,875,876,877,878,879,880,881,882,883,884,885,886,887,888,889,890,891,892,893,894,895,896,897,898,899,900,901,902,903,904,905,906,907,1031,1033,1035,1037,1039,1041,1043,1045,1047,1049,1051,1053
+
+### Agent Prompt
+
+```
+BATCH 50: JetStream Cluster 1 Integration Tests (118 tests)
+
+Port 118 cluster integration tests from Go to C#. These test cluster formation, stream replication, and leader election.
+
+GO SOURCE FILES (read this first):
+ - golang/nats-server/server/jetstream_cluster_1_test.go (118 tests)
+
+.NET TARGET FILE (create):
+ - dotnet/tests/ZB.MOM.NatsNet.Server.IntegrationTests/JetStream/JetStreamCluster1Tests.cs
+
+HARNESS APIs AVAILABLE (under Helpers/):
+ - TestCluster.CreateJetStreamCluster(numServers, name) — multi-server cluster
+ - TestCluster.CreateJetStreamClusterWithTemplate(template, numServers, name)
+ - cluster.WaitOnClusterReady(), WaitOnLeader(), WaitOnStreamLeader(account, stream)
+ - cluster.Leader(), RandomServer(), ServerByName(name)
+ - NatsTestClient.ConnectToServer(server)
+ - CheckHelper.CheckFor(timeout, interval, check)
+ - ConfigHelper.JsClusterTemplate, CreateConfigFile(content)
+ - IntegrationTestBase — base class with Skip guard
+
+PORTING PATTERN:
+Class inherits IntegrationTestBase, uses [SkippableFact]/[SkippableTheory].
+Most tests use: `using var c = TestCluster.CreateJetStreamCluster(3, "R3");`
+Then connect to a server: `using var nc = NatsTestClient.ConnectToServer(c.RandomServer());`
+Port full Go test logic with Shouldly assertions.
+
+TEST IDS (118):
+758,759,760,762,764,766,768,770,772,774,776,778,780,782,784,786,788,790,792,794,796,798,800,802,804,806,808,810,812,814,816,818,820,822,824,826,828,830,832,834,836,838,840,842,844,846,847,848,849,850,851,852,853,854,855,856,857,858,859,860,861,862,863,864,865,866,867,868,869,870,871,872,873,874,875,876,877,878,879,880,881,882,883,884,885,886,887,888,889,890,891,892,893,894,895,896,897,898,899,900,901,902,903,904,905,906,907,1031,1033,1035,1037,1039,1041,1043,1045,1047,1049,1051,1053
+
+BUILD: dotnet build dotnet/tests/ZB.MOM.NatsNet.Server.IntegrationTests/
+VERIFY: dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --no-build -c Debug
+COMMIT: "test(batch50): port 118 JetStream cluster 1 integration tests"
+```
+
+---
+
+## Task 4: Batch 51 — JetStream Cluster 2 (106 tests)
+
+**Batch**: 51
+**Tests**: 106
+**Blocked by**: Batch 48 (Task 1)
+
+### Go Source Files
+
+| File | Test Count |
+|------|-----------|
+| `golang/nats-server/server/jetstream_cluster_2_test.go` | 106 |
+
+### .NET Target Files
+
+| File | Source |
+|------|--------|
+| `JetStream/JetStreamCluster2Tests.cs` | jetstream_cluster_2_test.go |
+
+### Test IDs (porting.db)
+
+**jetstream_cluster_2_test.go** (106): 908,909,910,911,912,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,930,931,932,933,934,935,936,937,938,939,940,941,942,943,944,945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,962,963,964,965,966,967,968,969,970,971,972,973,974,975,976,977,978,979,980,981,982,983,984,985,986,987,988,989,990,991,992,993,994,995,996,997,998,999,1000,1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1011,1012,1030
+
+### Agent Prompt
+
+```
+BATCH 51: JetStream Cluster 2 Integration Tests (106 tests)
+
+Port 106 cluster integration tests. These test consumer replication, failover, and recovery.
+
+GO SOURCE FILES (read this first):
+ - golang/nats-server/server/jetstream_cluster_2_test.go (106 tests)
+
+.NET TARGET FILE (create):
+ - dotnet/tests/ZB.MOM.NatsNet.Server.IntegrationTests/JetStream/JetStreamCluster2Tests.cs
+
+HARNESS APIs AVAILABLE (under Helpers/):
+ - TestCluster.CreateJetStreamCluster(numServers, name)
+ - TestCluster.CreateJetStreamClusterWithTemplate(template, numServers, name)
+ - cluster.WaitOnClusterReady(), WaitOnLeader(), WaitOnStreamLeader(), WaitOnConsumerLeader()
+ - cluster.StreamLeader(), ConsumerLeader(), Leader(), RandomServer(), ServerByName()
+ - cluster.StopAll(), RestartAll()
+ - NatsTestClient.ConnectToServer(server)
+ - CheckHelper.CheckFor(timeout, interval, check)
+ - IntegrationTestBase — base class with Skip guard
+
+TEST IDS (106):
+908,909,910,911,912,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,930,931,932,933,934,935,936,937,938,939,940,941,942,943,944,945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,962,963,964,965,966,967,968,969,970,971,972,973,974,975,976,977,978,979,980,981,982,983,984,985,986,987,988,989,990,991,992,993,994,995,996,997,998,999,1000,1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1011,1012,1030
+
+BUILD: dotnet build dotnet/tests/ZB.MOM.NatsNet.Server.IntegrationTests/
+VERIFY: dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --no-build -c Debug
+COMMIT: "test(batch51): port 106 JetStream cluster 2 integration tests"
+```
+
+---
+
+## Task 5: Batch 52 — JetStream Cluster 3 (82 tests)
+
+**Batch**: 52
+**Tests**: 82
+**Blocked by**: Batch 48 (Task 1)
+
+### Go Source Files
+
+| File | Test Count |
+|------|-----------|
+| `golang/nats-server/server/jetstream_cluster_3_test.go` | 82 |
+
+### .NET Target Files
+
+| File | Source |
+|------|--------|
+| `JetStream/JetStreamCluster3Tests.cs` | jetstream_cluster_3_test.go |
+
+### Test IDs (porting.db)
+
+**jetstream_cluster_3_test.go** (82): 1031,1033,1035,1037,1039,1041,1043,1045,1047,1049,1051,1053,1055,1057,1059,1061,1063,1065,1067,1069,1071,1073,1075,1077,1079,1081,1083,1085,1087,1089,1091,1093,1095,1097,1099,1101,1103,1105,1107,1109,1111,1113,1115,1117,1119,1121,1123,1125,1127,1129,1131,1133,1135,1137,1139,1141,1143,1145,1147,1149,1151,1153,1155,1157,1159,1161,1163,1165,1167,1169,1171,1173,1175,1177,1179,1181,1183,1185,1187,1189,1191,1193
+
+### Agent Prompt
+
+```
+BATCH 52: JetStream Cluster 3 Integration Tests (82 tests)
+
+Port 82 advanced cluster scenario tests.
+
+GO SOURCE FILES (read this first):
+ - golang/nats-server/server/jetstream_cluster_3_test.go (82 tests)
+
+.NET TARGET FILE (create):
+ - dotnet/tests/ZB.MOM.NatsNet.Server.IntegrationTests/JetStream/JetStreamCluster3Tests.cs
+
+HARNESS APIs AVAILABLE (under Helpers/):
+ - TestCluster.CreateJetStreamCluster(numServers, name)
+ - TestCluster.CreateJetStreamClusterWithTemplate(template, numServers, name)
+ - cluster.WaitOnClusterReady(), WaitOnLeader(), WaitOnStreamLeader(), WaitOnConsumerLeader()
+ - cluster.StreamLeader(), ConsumerLeader(), Leader(), RandomServer()
+ - NatsTestClient.ConnectToServer(server)
+ - CheckHelper.CheckFor(timeout, interval, check)
+ - IntegrationTestBase — base class with Skip guard
+
+TEST IDS (82):
+1031,1033,1035,1037,1039,1041,1043,1045,1047,1049,1051,1053,1055,1057,1059,1061,1063,1065,1067,1069,1071,1073,1075,1077,1079,1081,1083,1085,1087,1089,1091,1093,1095,1097,1099,1101,1103,1105,1107,1109,1111,1113,1115,1117,1119,1121,1123,1125,1127,1129,1131,1133,1135,1137,1139,1141,1143,1145,1147,1149,1151,1153,1155,1157,1159,1161,1163,1165,1167,1169,1171,1173,1175,1177,1179,1181,1183,1185,1187,1189,1191,1193
+
+BUILD: dotnet build dotnet/tests/ZB.MOM.NatsNet.Server.IntegrationTests/
+VERIFY: dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --no-build -c Debug
+COMMIT: "test(batch52): port 82 JetStream cluster 3 integration tests"
+```
+
+---
+
+## Task 6: Batch 53 — JetStream Cluster 4 (75 tests)
+
+**Batch**: 53
+**Tests**: 75
+**Blocked by**: Batch 48 (Task 1)
+
+### Go Source Files
+
+| File | Test Count |
+|------|-----------|
+| `golang/nats-server/server/jetstream_cluster_4_test.go` | 75 |
+
+### .NET Target Files
+
+| File | Source |
+|------|--------|
+| `JetStream/JetStreamCluster4Tests.cs` | jetstream_cluster_4_test.go |
+
+### Test IDs (porting.db)
+
+**jetstream_cluster_4_test.go** (75): 1129,1130,1131,1132,1133,1134,1135,1136,1137,1138,1139,1140,1141,1142,1143,1144,1145,1146,1147,1148,1149,1150,1151,1152,1153,1154,1155,1156,1157,1158,1159,1160,1161,1162,1163,1164,1165,1166,1167,1168,1169,1170,1171,1172,1173,1174,1175,1176,1177,1178,1179,1180,1181,1182,1183,1184,1185,1186,1187,1188,1189,1190,1191,1192,1193,1194,1195,1196,1197,1198,1199,1200,1201,1202,1210
+
+### Agent Prompt
+
+```
+BATCH 53: JetStream Cluster 4 Integration Tests (75 tests)
+
+Port 75 busy stream and consumption pattern tests.
+
+GO SOURCE FILES (read this first):
+ - golang/nats-server/server/jetstream_cluster_4_test.go (75 tests)
+
+.NET TARGET FILE (create):
+ - dotnet/tests/ZB.MOM.NatsNet.Server.IntegrationTests/JetStream/JetStreamCluster4Tests.cs
+
+HARNESS APIs AVAILABLE (under Helpers/):
+ - TestCluster.CreateJetStreamCluster(numServers, name)
+ - TestCluster.CreateJetStreamClusterWithTemplate(template, numServers, name)
+ - cluster.WaitOnClusterReady(), WaitOnLeader(), WaitOnStreamLeader(), WaitOnConsumerLeader()
+ - cluster.StreamLeader(), ConsumerLeader(), Leader(), RandomServer()
+ - NatsTestClient.ConnectToServer(server)
+ - CheckHelper.CheckFor(timeout, interval, check)
+ - IntegrationTestBase — base class with Skip guard
+
+TEST IDS (75):
+1129,1130,1131,1132,1133,1134,1135,1136,1137,1138,1139,1140,1141,1142,1143,1144,1145,1146,1147,1148,1149,1150,1151,1152,1153,1154,1155,1156,1157,1158,1159,1160,1161,1162,1163,1164,1165,1166,1167,1168,1169,1170,1171,1172,1173,1174,1175,1176,1177,1178,1179,1180,1181,1182,1183,1184,1185,1186,1187,1188,1189,1190,1191,1192,1193,1194,1195,1196,1197,1198,1199,1200,1201,1202,1210
+
+BUILD: dotnet build dotnet/tests/ZB.MOM.NatsNet.Server.IntegrationTests/
+VERIFY: dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --no-build -c Debug
+COMMIT: "test(batch53): port 75 JetStream cluster 4 integration tests"
+```
+
+---
+
+## Task 7: Batch 54 — MQTT (78 tests)
+
+**Batch**: 54
+**Tests**: 78 (77 + 1)
+**Blocked by**: Batch 48 (Task 1)
+
+### Go Source Files
+
+| File | Test Count |
+|------|-----------|
+| `golang/nats-server/server/mqtt_test.go` | 77 |
+| `golang/nats-server/server/mqtt_ex_test_test.go` | 1 |
+
+### .NET Target Files
+
+| File | Source |
+|------|--------|
+| `Mqtt/MqttTests.cs` | mqtt_test.go + mqtt_ex_test_test.go |
+
+### Test IDs (porting.db)
+
+**mqtt_test.go** (77): 2174,2175,2176,2177,2178,2179,2180,2181,2182,2183,2184,2185,2186,2187,2188,2189,2190,2191,2192,2193,2194,2195,2196,2197,2198,2199,2200,2201,2202,2203,2204,2205,2206,2207,2208,2209,2210,2211,2212,2213,2214,2215,2216,2217,2218,2219,2220,2221,2222,2223,2224,2225,2226,2227,2228,2229,2230,2231,2232,2233,2234,2235,2236,2237,2238,2239,2240,2241,2242,2243,2244,2245,2246,2247,2248,2249,2328
+
+**mqtt_ex_test_test.go** (1): 2169
+
+### Agent Prompt
+
+```
+BATCH 54: MQTT Integration Tests (78 tests)
+
+Port 78 MQTT protocol integration tests.
+
+GO SOURCE FILES (read these first):
+ - golang/nats-server/server/mqtt_test.go (77 tests)
+ - golang/nats-server/server/mqtt_ex_test_test.go (1 test)
+
+.NET TARGET FILE (create):
+ - dotnet/tests/ZB.MOM.NatsNet.Server.IntegrationTests/Mqtt/MqttTests.cs
+
+HARNESS APIs AVAILABLE (under Helpers/):
+ - TestServerHelper.RunBasicJetStreamServer(Output) — MQTT needs JetStream enabled
+ - TestServerHelper.RunServerWithConfig(configFile) — for MQTT-specific configs
+ - NatsTestClient.Connect(url)
+ - CheckHelper.CheckFor(timeout, interval, check)
+ - ConfigHelper.CreateConfigFile(content)
+ - IntegrationTestBase — base class with Skip guard
+
+NOTE: MQTT tests may need raw TCP connections for MQTT protocol testing.
+Create a simple MqttTestClient helper within the test file if needed,
+or use System.Net.Sockets.TcpClient for raw MQTT packet exchange.
+Mirror the Go mqttNewClient / mqttConnect helpers from mqtt_test.go.
+
+TEST IDS — mqtt_test.go (77):
+2174,2175,2176,2177,2178,2179,2180,2181,2182,2183,2184,2185,2186,2187,2188,2189,2190,2191,2192,2193,2194,2195,2196,2197,2198,2199,2200,2201,2202,2203,2204,2205,2206,2207,2208,2209,2210,2211,2212,2213,2214,2215,2216,2217,2218,2219,2220,2221,2222,2223,2224,2225,2226,2227,2228,2229,2230,2231,2232,2233,2234,2235,2236,2237,2238,2239,2240,2241,2242,2243,2244,2245,2246,2247,2248,2249,2328
+
+TEST IDS — mqtt_ex_test_test.go (1): 2169
+
+BUILD: dotnet build dotnet/tests/ZB.MOM.NatsNet.Server.IntegrationTests/
+VERIFY: dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --no-build -c Debug
+COMMIT: "test(batch54): port 78 MQTT integration tests"
+```
+
+---
+
+## Task 8: Batch 55 — NoRace (75 tests)
+
+**Batch**: 55
+**Tests**: 75 (51 + 24)
+**Blocked by**: Batch 48 (Task 1)
+
+### Go Source Files
+
+| File | Test Count |
+|------|-----------|
+| `golang/nats-server/server/norace_1_test.go` | 51 |
+| `golang/nats-server/server/norace_2_test.go` | 24 |
+
+### .NET Target Files
+
+| File | Source |
+|------|--------|
+| `NoRace/NoRace1Tests.cs` | norace_1_test.go |
+| `NoRace/NoRace2Tests.cs` | norace_2_test.go |
+
+### Test IDs (porting.db)
+
+**norace_1_test.go** (51): 2379,2386,2387,2388,2389,2390,2391,2392,2393,2394,2395,2396,2397,2398,2399,2400,2401,2402,2403,2404,2405,2406,2407,2408,2409,2410,2411,2412,2413,2414,2415,2416,2417,2418,2419,2420,2421,2422,2423,2424,2425,2426,2427,2428,2429,2430,2431,2432,2433,2434,2465
+
+**norace_2_test.go** (24): 2471,2472,2473,2474,2475,2476,2477,2478,2479,2480,2481,2482,2483,2484,2485,2486,2487,2488,2489,2490,2491,2492,2493,2494,2509
+
+### Agent Prompt
+
+```
+BATCH 55: NoRace Integration Tests (75 tests)
+
+Port 75 concurrency tests. In Go these are built with `//go:build !race` to exclude from race detector runs.
+
+GO SOURCE FILES (read these first):
+ - golang/nats-server/server/norace_1_test.go (51 tests)
+ - golang/nats-server/server/norace_2_test.go (24 tests)
+
+.NET TARGET FILES (create):
+ - dotnet/tests/ZB.MOM.NatsNet.Server.IntegrationTests/NoRace/NoRace1Tests.cs
+ - dotnet/tests/ZB.MOM.NatsNet.Server.IntegrationTests/NoRace/NoRace2Tests.cs
+
+HARNESS APIs AVAILABLE (under Helpers/):
+ - TestServerHelper.RunBasicJetStreamServer(Output)
+ - TestCluster.CreateJetStreamCluster(numServers, name)
+ - NatsTestClient.Connect(url) / ConnectToServer(server)
+ - CheckHelper.CheckFor(timeout, interval, check)
+ - IntegrationTestBase — base class with Skip guard
+
+SPECIAL: Add [Trait("Category", "NoRace")] to both test classes (in addition to "Integration").
+These tests stress concurrency so they may use Task.WhenAll, Parallel.ForEachAsync, etc.
+
+TEST IDS — norace_1_test.go (51):
+2379,2386,2387,2388,2389,2390,2391,2392,2393,2394,2395,2396,2397,2398,2399,2400,2401,2402,2403,2404,2405,2406,2407,2408,2409,2410,2411,2412,2413,2414,2415,2416,2417,2418,2419,2420,2421,2422,2423,2424,2425,2426,2427,2428,2429,2430,2431,2432,2433,2434,2465
+
+TEST IDS — norace_2_test.go (24):
+2471,2472,2473,2474,2475,2476,2477,2478,2479,2480,2481,2482,2483,2484,2485,2486,2487,2488,2489,2490,2491,2492,2493,2494,2509
+
+BUILD: dotnet build dotnet/tests/ZB.MOM.NatsNet.Server.IntegrationTests/
+VERIFY: dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --no-build -c Debug
+COMMIT: "test(batch55): port 75 NoRace integration tests"
+```
+
+---
+
+## Task 9: Batch 56 — Reload + Auth (66 tests)
+
+**Batch**: 56
+**Tests**: 66 (44 + 5 + 5 + 11 + 1)
+**Blocked by**: Batch 48 (Task 1)
+
+### Go Source Files
+
+| File | Test Count |
+|------|-----------|
+| `golang/nats-server/server/reload_test.go` | 44 |
+| `golang/nats-server/server/accounts_test.go` | 5 |
+| `golang/nats-server/server/auth_callout_test.go` | 5 |
+| `golang/nats-server/server/jwt_test.go` | 11 |
+| `golang/nats-server/server/opts_test.go` | 1 |
+
+### .NET Target Files
+
+| File | Source |
+|------|--------|
+| `Config/ReloadTests.cs` | reload_test.go, opts_test.go |
+| `Auth/AuthIntegrationTests.cs` | accounts_test.go, auth_callout_test.go, jwt_test.go |
+
+### Test IDs (porting.db)
+
+**reload_test.go** (44): 2721,2722,2723,2724,2725,2726,2727,2728,2729,2730,2731,2732,2733,2734,2735,2736,2737,2738,2739,2740,2741,2742,2743,2744,2745,2746,2747,2748,2749,2750,2751,2752,2753,2754,2755,2756,2757,2758,2759,2760,2761,2762,2763,2793
+
+**accounts_test.go** (5): 86,87,89,105,108
+
+**auth_callout_test.go** (5): 115,117,138,140,141
+
+**jwt_test.go** (11): 1819,1821,1823,1825,1827,1829,1831,1833,1835,1837,1896
+
+**opts_test.go** (1): 2551
+
+### Agent Prompt
+
+```
+BATCH 56: Reload + Auth Integration Tests (66 tests)
+
+Port 66 config reload and authentication tests.
+
+GO SOURCE FILES (read these first):
+ - golang/nats-server/server/reload_test.go (44 tests — config hot-reload)
+ - golang/nats-server/server/accounts_test.go (5 tests — route account mappings)
+ - golang/nats-server/server/auth_callout_test.go (5 tests — external auth callout)
+ - golang/nats-server/server/jwt_test.go (11 tests — JWT validation)
+ - golang/nats-server/server/opts_test.go (1 test)
+
+.NET TARGET FILES (create):
+ - dotnet/tests/ZB.MOM.NatsNet.Server.IntegrationTests/Config/ReloadTests.cs
+ (44 reload + 1 opts test)
+ - dotnet/tests/ZB.MOM.NatsNet.Server.IntegrationTests/Auth/AuthIntegrationTests.cs
+ (5 accounts + 5 auth_callout + 11 jwt tests)
+
+HARNESS APIs AVAILABLE (under Helpers/):
+ - TestServerHelper.RunServer(opts) / RunServerWithConfig(configFile)
+ - TestServerHelper.RunBasicJetStreamServer(Output)
+ - NatsTestClient.Connect(url) / ConnectToServer(server)
+ - CheckHelper.CheckFor(timeout, interval, check)
+ - ConfigHelper.CreateConfigFile(content)
+ - IntegrationTestBase — base class with Skip guard
+
+NOTE: Reload tests typically write a config file, start a server, modify the file, then trigger reload.
+JWT tests need to generate test JWTs — use System.IdentityModel.Tokens.Jwt or create test JWT strings inline.
+
+TEST IDS — reload_test.go (44):
+2721,2722,2723,2724,2725,2726,2727,2728,2729,2730,2731,2732,2733,2734,2735,2736,2737,2738,2739,2740,2741,2742,2743,2744,2745,2746,2747,2748,2749,2750,2751,2752,2753,2754,2755,2756,2757,2758,2759,2760,2761,2762,2763,2793
+
+TEST IDS — accounts_test.go (5): 86,87,89,105,108
+TEST IDS — auth_callout_test.go (5): 115,117,138,140,141
+TEST IDS — jwt_test.go (11): 1819,1821,1823,1825,1827,1829,1831,1833,1835,1837,1896
+TEST IDS — opts_test.go (1): 2551
+
+BUILD: dotnet build dotnet/tests/ZB.MOM.NatsNet.Server.IntegrationTests/
+VERIFY: dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --no-build -c Debug
+COMMIT: "test(batch56): port 66 reload and auth integration tests"
+```
+
+---
+
+## Task 10: Batch 57 — SuperCluster + LeafNode (53 tests)
+
+**Batch**: 57
+**Tests**: 53 (36 + 3 + 14)
+**Blocked by**: Batch 48 (Task 1)
+
+### Go Source Files
+
+| File | Test Count |
+|------|-----------|
+| `golang/nats-server/server/jetstream_super_cluster_test.go` | 36 |
+| `golang/nats-server/server/jetstream_leafnode_test.go` | 3 |
+| `golang/nats-server/server/leafnode_test.go` | 14 |
+
+### .NET Target Files
+
+| File | Source |
+|------|--------|
+| `JetStream/JetStreamSuperClusterTests.cs` | jetstream_super_cluster_test.go, jetstream_leafnode_test.go |
+| `LeafNode/LeafNodeTests.cs` | leafnode_test.go |
+
+### Test IDs (porting.db)
+
+**jetstream_super_cluster_test.go** (36): 1419,1420,1421,1422,1423,1424,1425,1426,1427,1428,1429,1430,1431,1432,1433,1434,1435,1436,1437,1438,1439,1440,1441,1442,1443,1444,1445,1446,1447,1448,1449,1450,1451,1452,1453,1464
+
+**jetstream_leafnode_test.go** (3): 1412,1413,1414
+
+**leafnode_test.go** (14): 1924,1930,1936,1942,1948,1954,1960,1966,1972,1978,1984,1990,1996,2004
+
+### Agent Prompt
+
+```
+BATCH 57: SuperCluster + LeafNode Integration Tests (53 tests)
+
+Port 53 multi-cluster and leaf node tests.
+
+GO SOURCE FILES (read these first):
+ - golang/nats-server/server/jetstream_super_cluster_test.go (36 tests)
+ - golang/nats-server/server/jetstream_leafnode_test.go (3 tests)
+ - golang/nats-server/server/leafnode_test.go (14 tests)
+
+.NET TARGET FILES (create):
+ - dotnet/tests/ZB.MOM.NatsNet.Server.IntegrationTests/JetStream/JetStreamSuperClusterTests.cs
+ (36 super cluster + 3 JS leafnode tests)
+ - dotnet/tests/ZB.MOM.NatsNet.Server.IntegrationTests/LeafNode/LeafNodeTests.cs
+ (14 leafnode tests)
+
+HARNESS APIs AVAILABLE (under Helpers/):
+ - TestSuperCluster.CreateJetStreamSuperCluster(numPerCluster, numClusters)
+ - supercluster.Leader(), RandomServer(), WaitOnLeader(), WaitOnStreamLeader(), ClusterForName()
+ - TestCluster.CreateJetStreamCluster(numServers, name)
+ - TestServerHelper.RunServer(opts) / RunServerWithConfig(configFile)
+ - NatsTestClient.Connect(url) / ConnectToServer(server)
+ - CheckHelper.CheckFor(timeout, interval, check)
+ - CheckHelper.CheckLeafNodeConnectedCount(server, expected)
+ - ConfigHelper.JsSuperClusterTemplate, CreateConfigFile(content)
+ - IntegrationTestBase — base class with Skip guard
+
+TEST IDS — jetstream_super_cluster_test.go (36):
+1419,1420,1421,1422,1423,1424,1425,1426,1427,1428,1429,1430,1431,1432,1433,1434,1435,1436,1437,1438,1439,1440,1441,1442,1443,1444,1445,1446,1447,1448,1449,1450,1451,1452,1453,1464
+
+TEST IDS — jetstream_leafnode_test.go (3): 1412,1413,1414
+TEST IDS — leafnode_test.go (14): 1924,1930,1936,1942,1948,1954,1960,1966,1972,1978,1984,1990,1996,2004
+
+BUILD: dotnet build dotnet/tests/ZB.MOM.NatsNet.Server.IntegrationTests/
+VERIFY: dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --no-build -c Debug
+COMMIT: "test(batch57): port 53 SuperCluster and LeafNode integration tests"
+```
+
+---
+
+## Task 11: Batch 58 — JetStream Misc (55 tests)
+
+**Batch**: 58
+**Tests**: 55 (26 + 11 + 9 + 2 + 2 + 4 + 1)
+**Blocked by**: Batch 48 (Task 1)
+
+### Go Source Files
+
+| File | Test Count |
+|------|-----------|
+| `golang/nats-server/server/jetstream_batching_test.go` | 26 |
+| `golang/nats-server/server/jetstream_benchmark_test.go` | 11 |
+| `golang/nats-server/server/jetstream_jwt_test.go` | 9 |
+| `golang/nats-server/server/jetstream_versioning_test.go` | 2 |
+| `golang/nats-server/server/jetstream_meta_benchmark_test.go` | 2 |
+| `golang/nats-server/server/jetstream_cluster_long_test.go` | 4 |
+| `golang/nats-server/server/jetstream_sourcing_scaling_test.go` | 1 |
+
+### .NET Target Files
+
+| File | Source |
+|------|--------|
+| `JetStream/JetStreamBatchingIntegrationTests.cs` | jetstream_batching_test.go |
+| `JetStream/JetStreamMiscTests.cs` | All other files (benchmark, jwt, versioning, meta_benchmark, cluster_long, sourcing_scaling) |
+
+### Test IDs (porting.db)
+
+**jetstream_batching_test.go** (26): 716,717,718,719,720,721,722,723,724,725,726,727,728,729,730,731,732,733,734,735,736,737,738,739,740,744
+
+**jetstream_benchmark_test.go** (11): 745,746,747,748,749,750,751,752,753,754,756
+
+**jetstream_jwt_test.go** (9): 1387,1389,1391,1393,1395,1397,1399,1400,1401
+
+**jetstream_versioning_test.go** (2): 1803,1805
+
+**jetstream_meta_benchmark_test.go** (2): 1416,1417
+
+**jetstream_cluster_long_test.go** (4): 1213,1215,1216,1218
+
+**jetstream_sourcing_scaling_test.go** (1): 1418
+
+### Agent Prompt
+
+```
+BATCH 58: JetStream Misc Integration Tests (55 tests)
+
+Port 55 JetStream miscellaneous tests (batching, benchmarks, JWT, versioning, long-running, scaling).
+
+GO SOURCE FILES (read these first):
+ - golang/nats-server/server/jetstream_batching_test.go (26 tests)
+ - golang/nats-server/server/jetstream_benchmark_test.go (11 tests)
+ - golang/nats-server/server/jetstream_jwt_test.go (9 tests)
+ - golang/nats-server/server/jetstream_versioning_test.go (2 tests)
+ - golang/nats-server/server/jetstream_meta_benchmark_test.go (2 tests)
+ - golang/nats-server/server/jetstream_cluster_long_test.go (4 tests)
+ - golang/nats-server/server/jetstream_sourcing_scaling_test.go (1 test)
+
+.NET TARGET FILES (create):
+ - dotnet/tests/ZB.MOM.NatsNet.Server.IntegrationTests/JetStream/JetStreamBatchingIntegrationTests.cs
+ (26 batching tests)
+ - dotnet/tests/ZB.MOM.NatsNet.Server.IntegrationTests/JetStream/JetStreamMiscTests.cs
+ (11 benchmark + 9 jwt + 2 versioning + 2 meta benchmark + 4 cluster long + 1 scaling = 29 tests)
+
+HARNESS APIs AVAILABLE (under Helpers/):
+ - TestServerHelper.RunBasicJetStreamServer(Output)
+ - TestCluster.CreateJetStreamCluster(numServers, name)
+ - NatsTestClient.Connect(url) / ConnectToServer(server)
+ - CheckHelper.CheckFor(timeout, interval, check)
+ - IntegrationTestBase — base class with Skip guard
+
+NOTE: Benchmark tests should be ported as regular integration tests (not BenchmarkDotNet).
+They test correctness of batching/throughput behavior, not performance measurement.
+
+TEST IDS — jetstream_batching_test.go (26):
+716,717,718,719,720,721,722,723,724,725,726,727,728,729,730,731,732,733,734,735,736,737,738,739,740,744
+
+TEST IDS — jetstream_benchmark_test.go (11): 745,746,747,748,749,750,751,752,753,754,756
+TEST IDS — jetstream_jwt_test.go (9): 1387,1389,1391,1393,1395,1397,1399,1400,1401
+TEST IDS — jetstream_versioning_test.go (2): 1803,1805
+TEST IDS — jetstream_meta_benchmark_test.go (2): 1416,1417
+TEST IDS — jetstream_cluster_long_test.go (4): 1213,1215,1216,1218
+TEST IDS — jetstream_sourcing_scaling_test.go (1): 1418
+
+BUILD: dotnet build dotnet/tests/ZB.MOM.NatsNet.Server.IntegrationTests/
+VERIFY: dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --no-build -c Debug
+COMMIT: "test(batch58): port 55 JetStream misc integration tests"
+```
+
+---
+
+## Task 12: Batch 59 — Events + Monitor + Misc (50 tests)
+
+**Batch**: 59
+**Tests**: 50 (13 + 15 + 7 + 5 + 6 + 1 + 1 + 1 + 1)
+**Blocked by**: Batch 48 (Task 1)
+
+### Go Source Files
+
+| File | Test Count |
+|------|-----------|
+| `golang/nats-server/server/events_test.go` | 13 |
+| `golang/nats-server/server/monitor_test.go` | 15 |
+| `golang/nats-server/server/msgtrace_test.go` | 7 |
+| `golang/nats-server/server/routes_test.go` | 5 |
+| `golang/nats-server/server/filestore_test.go` | 6 |
+| `golang/nats-server/server/server_test.go` | 1 |
+| `golang/nats-server/server/memstore_test.go` | 1 |
+| `golang/nats-server/server/gateway_test.go` | 1 |
+| `golang/nats-server/server/websocket_test.go` | 1 |
+
+### .NET Target Files
+
+| File | Source |
+|------|--------|
+| `Events/EventsTests.cs` | events_test.go |
+| `Monitor/MonitorIntegrationTests.cs` | monitor_test.go |
+| `MiscTests.cs` | msgtrace_test.go, routes_test.go, filestore_test.go, server_test.go, memstore_test.go, gateway_test.go, websocket_test.go |
+
+### Test IDs (porting.db)
+
+**events_test.go** (13): 303,304,305,306,307,308,309,310,311,314,315,346,347
+
+**monitor_test.go** (15): 2064,2087,2088,2089,2090,2091,2092,2093,2094,2095,2096,2097,2098,2163,2165
+
+**msgtrace_test.go** (7): 2329,2330,2331,2332,2333,2350,2351
+
+**routes_test.go** (5): 2815,2831,2837,2851,2857
+
+**filestore_test.go** (6): 493,552,553,554,569,598
+
+**server_test.go** (1): 2893
+
+**memstore_test.go** (1): 2057
+
+**gateway_test.go** (1): 683
+
+**websocket_test.go** (1): 3095
+
+### Agent Prompt
+
+```
+BATCH 59: Events + Monitor + Misc Integration Tests (50 tests)
+
+Port 50 miscellaneous integration tests across events, monitoring, routing, stores, and protocols.
+
+GO SOURCE FILES (read these first):
+ - golang/nats-server/server/events_test.go (13 tests)
+ - golang/nats-server/server/monitor_test.go (15 tests)
+ - golang/nats-server/server/msgtrace_test.go (7 tests)
+ - golang/nats-server/server/routes_test.go (5 tests)
+ - golang/nats-server/server/filestore_test.go (6 tests)
+ - golang/nats-server/server/server_test.go (1 test)
+ - golang/nats-server/server/memstore_test.go (1 test)
+ - golang/nats-server/server/gateway_test.go (1 test)
+ - golang/nats-server/server/websocket_test.go (1 test)
+
+.NET TARGET FILES (create):
+ - dotnet/tests/ZB.MOM.NatsNet.Server.IntegrationTests/Events/EventsTests.cs
+ (13 event system tests)
+ - dotnet/tests/ZB.MOM.NatsNet.Server.IntegrationTests/Monitor/MonitorIntegrationTests.cs
+ (15 monitoring endpoint tests)
+ - dotnet/tests/ZB.MOM.NatsNet.Server.IntegrationTests/MiscTests.cs
+ (7 msgtrace + 5 routes + 6 filestore + 1 server + 1 memstore + 1 gateway + 1 websocket = 22 tests)
+
+HARNESS APIs AVAILABLE (under Helpers/):
+ - TestServerHelper.RunServer(opts) / RunBasicJetStreamServer(Output) / RunServerWithConfig(configFile)
+ - TestCluster.CreateJetStreamCluster(numServers, name)
+ - NatsTestClient.Connect(url) / ConnectToServer(server)
+ - CheckHelper.CheckFor(timeout, interval, check) / CheckClusterFormed(servers)
+ - ConfigHelper.CreateConfigFile(content)
+ - IntegrationTestBase — base class with Skip guard
+
+NOTE: Monitor tests may use HTTP requests (HttpClient) to hit monitoring endpoints.
+Events tests use system subscriptions to observe server events.
+Routes/Gateway/Websocket tests may need cluster or multi-server setups.
+
+TEST IDS — events_test.go (13): 303,304,305,306,307,308,309,310,311,314,315,346,347
+TEST IDS — monitor_test.go (15): 2064,2087,2088,2089,2090,2091,2092,2093,2094,2095,2096,2097,2098,2163,2165
+TEST IDS — msgtrace_test.go (7): 2329,2330,2331,2332,2333,2350,2351
+TEST IDS — routes_test.go (5): 2815,2831,2837,2851,2857
+TEST IDS — filestore_test.go (6): 493,552,553,554,569,598
+TEST IDS — server_test.go (1): 2893
+TEST IDS — memstore_test.go (1): 2057
+TEST IDS — gateway_test.go (1): 683
+TEST IDS — websocket_test.go (1): 3095
+
+BUILD: dotnet build dotnet/tests/ZB.MOM.NatsNet.Server.IntegrationTests/
+VERIFY: dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --no-build -c Debug
+COMMIT: "test(batch59): port 50 events, monitor, and misc integration tests"
+```
+
+---
+
+## Task 13: Post-Merge Reconciliation
+
+**Blocked by**: All test batches (Tasks 2-12)
+
+### Steps
+
+1. After all 12 batch branches are merged to main:
+
+2. **Build verification**:
+ ```bash
+ dotnet build dotnet/
+ ```
+
+3. **Integration test run** (all should skip):
+ ```bash
+ dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.IntegrationTests/ -v n
+ ```
+
+4. **Unit test regression check**:
+ ```bash
+ dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/
+ ```
+
+5. **PortTracker reconciliation**:
+ ```bash
+ # Reset deferred tests to unknown
+ sqlite3 porting.db "UPDATE unit_tests SET status='unknown' WHERE status='deferred';"
+
+ # Run audit to auto-detect
+ dotnet run --project tools/NatsNet.PortTracker -- audit --type tests --db porting.db --execute
+
+ # Check how many promoted
+ sqlite3 porting.db "SELECT status, COUNT(*) FROM unit_tests GROUP BY status;"
+
+ # Bulk-promote any remaining to verified (after confirming they exist)
+ sqlite3 porting.db "UPDATE unit_tests SET status='verified' WHERE status='unknown';"
+ ```
+
+6. **Generate report**:
+ ```bash
+ ./reports/generate-report.sh
+ git add -f reports/current.md
+ ```
+
+7. **Commit**:
+ ```bash
+ git commit -m "chore(integration-tests): reconcile porting.db after all test batches merged"
+ ```
+
+### Expected Final State
+
+- **Tests**: 2066 + 884 = 2950 verified (all unit_tests accounted for)
+- **Features**: 3626 verified, 22 complete, 24 n/a, 1 stub
+- **Overall**: ~6941/6942 items (99.9%)
+
+---
+
+## Agent Launch Commands
+
+### Wave 1: Harness (foreground, must complete first)
+
+```
+Agent(
+ description="Batch 48: test harness",
+ subagent_type="general-purpose",
+ model="sonnet",
+ isolation="worktree",
+ prompt=""
+)
+```
+
+After merge to main, proceed to Wave 2.
+
+### Wave 2: All Test Batches (background, parallel)
+
+Launch all 11 agents simultaneously with `run_in_background: true`:
+
+```
+Agent(subagent_type="general-purpose", model="sonnet", isolation="worktree", run_in_background=true, description="Batch 49: JS core tests", prompt="")
+Agent(subagent_type="general-purpose", model="sonnet", isolation="worktree", run_in_background=true, description="Batch 50: JS cluster 1", prompt="")
+Agent(subagent_type="general-purpose", model="sonnet", isolation="worktree", run_in_background=true, description="Batch 51: JS cluster 2", prompt="")
+Agent(subagent_type="general-purpose", model="sonnet", isolation="worktree", run_in_background=true, description="Batch 52: JS cluster 3", prompt="")
+Agent(subagent_type="general-purpose", model="sonnet", isolation="worktree", run_in_background=true, description="Batch 53: JS cluster 4", prompt="")
+Agent(subagent_type="general-purpose", model="sonnet", isolation="worktree", run_in_background=true, description="Batch 54: MQTT tests", prompt="")
+Agent(subagent_type="general-purpose", model="sonnet", isolation="worktree", run_in_background=true, description="Batch 55: NoRace tests", prompt="")
+Agent(subagent_type="general-purpose", model="sonnet", isolation="worktree", run_in_background=true, description="Batch 56: Reload+Auth", prompt="")
+Agent(subagent_type="general-purpose", model="sonnet", isolation="worktree", run_in_background=true, description="Batch 57: SuperCluster", prompt="")
+Agent(subagent_type="general-purpose", model="sonnet", isolation="worktree", run_in_background=true, description="Batch 58: JS misc", prompt="")
+Agent(subagent_type="general-purpose", model="sonnet", isolation="worktree", run_in_background=true, description="Batch 59: Events+Monitor", prompt="")
+```
+
+### Wave 3: Reconciliation (after all Wave 2 merges)
+
+Run Task 13 manually or via agent after all branches merge.
diff --git a/docs/plans/2026-03-01-deferred-integration-tests-plan.md.tasks.json b/docs/plans/2026-03-01-deferred-integration-tests-plan.md.tasks.json
new file mode 100644
index 0000000..fdf38db
--- /dev/null
+++ b/docs/plans/2026-03-01-deferred-integration-tests-plan.md.tasks.json
@@ -0,0 +1,19 @@
+{
+ "planPath": "docs/plans/2026-03-01-deferred-integration-tests-plan.md",
+ "tasks": [
+ {"id": 15, "subject": "Task 1: Batch 48 — Test Harness Infrastructure", "status": "pending"},
+ {"id": 16, "subject": "Task 2: Batch 49 — JetStream Core (126 tests)", "status": "pending", "blockedBy": [15]},
+ {"id": 17, "subject": "Task 3: Batch 50 — JetStream Cluster 1 (118 tests)", "status": "pending", "blockedBy": [15]},
+ {"id": 18, "subject": "Task 4: Batch 51 — JetStream Cluster 2 (106 tests)", "status": "pending", "blockedBy": [15]},
+ {"id": 19, "subject": "Task 5: Batch 52 — JetStream Cluster 3 (82 tests)", "status": "pending", "blockedBy": [15]},
+ {"id": 20, "subject": "Task 6: Batch 53 — JetStream Cluster 4 (75 tests)", "status": "pending", "blockedBy": [15]},
+ {"id": 21, "subject": "Task 7: Batch 54 — MQTT (78 tests)", "status": "pending", "blockedBy": [15]},
+ {"id": 22, "subject": "Task 8: Batch 55 — NoRace (75 tests)", "status": "pending", "blockedBy": [15]},
+ {"id": 23, "subject": "Task 9: Batch 56 — Reload + Auth (66 tests)", "status": "pending", "blockedBy": [15]},
+ {"id": 24, "subject": "Task 10: Batch 57 — SuperCluster + LeafNode (53 tests)", "status": "pending", "blockedBy": [15]},
+ {"id": 25, "subject": "Task 11: Batch 58 — JetStream Misc (55 tests)", "status": "pending", "blockedBy": [15]},
+ {"id": 26, "subject": "Task 12: Batch 59 — Events + Monitor + Misc (50 tests)", "status": "pending", "blockedBy": [15]},
+ {"id": 27, "subject": "Task 13: Post-Merge Reconciliation", "status": "pending", "blockedBy": [16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26]}
+ ],
+ "lastUpdated": "2026-03-01T17:00:00Z"
+}
diff --git a/dotnet/tests/ZB.MOM.NatsNet.Server.IntegrationTests/JetStream/JetStreamCluster1Tests.cs b/dotnet/tests/ZB.MOM.NatsNet.Server.IntegrationTests/JetStream/JetStreamCluster1Tests.cs
new file mode 100644
index 0000000..6a2b150
--- /dev/null
+++ b/dotnet/tests/ZB.MOM.NatsNet.Server.IntegrationTests/JetStream/JetStreamCluster1Tests.cs
@@ -0,0 +1,1617 @@
+// Copyright 2020-2025 The NATS Authors
+// Licensed under the Apache License, Version 2.0
+//
+// Ported from golang/nats-server/server/jetstream_cluster_1_test.go
+// These tests require a running JetStream cluster. They are skipped unless
+// NATS_INTEGRATION_TESTS=true is set in the environment.
+
+using Xunit.Sdk;
+
+namespace ZB.MOM.NatsNet.Server.IntegrationTests.JetStream;
+
+///
+/// Integration tests for JetStream cluster functionality: cluster formation,
+/// stream replication, consumer state, leader election, and catchup.
+/// Ported from Go's TestJetStreamCluster* tests (first 118).
+///
+[Trait("Category", "Integration")]
+public class JetStreamCluster1Tests : IntegrationTestBase
+{
+ public JetStreamCluster1Tests(ITestOutputHelper output) : base(output) { }
+
+ // -----------------------------------------------------------------------
+ // 1. TestJetStreamClusterConfig
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterConfig_ShouldRequireServerNameAndClusterName()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ // Verifies that a JetStream cluster node requires server_name and cluster.name.
+ // Corresponds to Go TestJetStreamClusterConfig.
+ using var c = TestCluster.CreateJetStreamCluster(1, "JSC");
+ c.WaitOnClusterReady();
+ }
+
+ // -----------------------------------------------------------------------
+ // 2. TestJetStreamClusterLeader
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterLeader_ShouldElectNewLeaderAfterShutdown()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "JSC");
+ c.WaitOnLeader();
+ var leader = c.Leader();
+ // Kill leader — new leader should be elected.
+ // Kill again — no leader (loss of quorum).
+ c.WaitOnLeader();
+ }
+
+ // -----------------------------------------------------------------------
+ // 3. TestJetStreamClusterExpand
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterExpand_ShouldAllowAddingNewServer()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(2, "JSC");
+ c.WaitOnPeerCount(2);
+ // Add a new server and wait for 3-peer cluster.
+ c.WaitOnPeerCount(3);
+ }
+
+ // -----------------------------------------------------------------------
+ // 4. TestJetStreamClusterAccountInfo
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterAccountInfo_ShouldReturnSingleResponse()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "JSC");
+ c.WaitOnLeader();
+ // Connect and send $JS.API.INFO, expect exactly one response.
+ using var nc = NatsTestClient.ConnectToServer(c.RandomServer());
+ }
+
+ // -----------------------------------------------------------------------
+ // 5. TestJetStreamClusterStreamLimitWithAccountDefaults
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterStreamLimitWithAccountDefaults_ShouldEnforceStorageLimits()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ // 2MB memory, 8MB disk limits template.
+ using var c = TestCluster.CreateJetStreamClusterWithTemplate(ConfigHelper.JsClusterTemplate, 3, "R3L");
+ c.WaitOnLeader();
+ }
+
+ // -----------------------------------------------------------------------
+ // 6. TestJetStreamClusterInfoRaftGroup
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterInfoRaftGroup_ShouldIncludeRaftGroupInStreamAndConsumerInfo()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R1S");
+ c.WaitOnLeader();
+ // Verify stream info and consumer info include cluster.raft_group field.
+ }
+
+ // -----------------------------------------------------------------------
+ // 7. TestJetStreamClusterSingleReplicaStreams
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterSingleReplicaStreams_ShouldSurviveLeaderRestart()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R1S");
+ c.WaitOnLeader();
+ // Create R=1 stream, publish 10 msgs, kill stream leader, restart, verify stream and consumer still exist.
+ c.WaitOnStreamLeader("$G", "TEST");
+ }
+
+ // -----------------------------------------------------------------------
+ // 8. TestJetStreamClusterMultiReplicaStreams
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterMultiReplicaStreams_ShouldReplicateAcrossCluster()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(5, "RNS");
+ c.WaitOnLeader();
+ // Create R=3 stream in 5-node cluster, publish 10 msgs, verify state.
+ }
+
+ // -----------------------------------------------------------------------
+ // 9. TestJetStreamClusterMultiReplicaStreamsDefaultFileMem
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterMultiReplicaStreamsDefaultFileMem_ShouldUseFileStorageByDefault()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ const string testConfig = @"
+listen: 127.0.0.1:-1
+server_name: %s
+jetstream: {store_dir: '%s'}
+
+cluster {
+ name: %s
+ listen: 127.0.0.1:%d
+ routes = [%s]
+}
+";
+ using var c = TestCluster.CreateJetStreamClusterWithTemplate(testConfig, 3, "RNS");
+ c.WaitOnLeader();
+ }
+
+ // -----------------------------------------------------------------------
+ // 10. TestJetStreamClusterMemoryStore
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterMemoryStore_ShouldReplicateMemoryStoredMessages()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3M");
+ c.WaitOnLeader();
+ // Create R=3 memory stream, publish 100 msgs, verify cluster info has 2 replicas.
+ }
+
+ // -----------------------------------------------------------------------
+ // 11. TestJetStreamClusterDelete
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterDelete_ShouldRemoveConsumerAndStream()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "RNS");
+ c.WaitOnLeader();
+ // Create stream C22 R=2, add consumer, delete consumer, delete stream, verify account info shows 0 streams.
+ }
+
+ // -----------------------------------------------------------------------
+ // 12. TestJetStreamClusterStreamPurge
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterStreamPurge_ShouldClearAllMessages()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(5, "R5S");
+ c.WaitOnLeader();
+ // Create R=3 stream in 5-node cluster, publish 100, purge, verify state shows 0 msgs.
+ }
+
+ // -----------------------------------------------------------------------
+ // 13. TestJetStreamClusterStreamUpdateSubjects
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterStreamUpdateSubjects_ShouldUpdateSubjectsSuccessfully()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Create stream on {foo, bar}, update to {bar, baz}, verify foo publish fails, baz succeeds.
+ }
+
+ // -----------------------------------------------------------------------
+ // 14. TestJetStreamClusterBadStreamUpdate
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterBadStreamUpdate_ShouldNotDeleteStreamOnBadConfig()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Attempt to update stream with invalid subject "foo..bar", verify original stream preserved.
+ }
+
+ // -----------------------------------------------------------------------
+ // 15. TestJetStreamClusterConsumerRedeliveredInfo
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterConsumerRedeliveredInfo_ShouldTrackRedeliveredCount()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Publish 1 msg, subscribe with AckWait=100ms, auto-unsubscribe after 2,
+ // verify NumRedelivered == 1 in ConsumerInfo.
+ }
+
+ // -----------------------------------------------------------------------
+ // 16. TestJetStreamClusterConsumerState
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterConsumerState_ShouldPreserveStateAfterLeaderChange()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(5, "R3S");
+ c.WaitOnLeader();
+ // Create R=3 stream, publish 10, pull-subscribe with "dlc", fetch 5 + ack,
+ // kill consumer leader, wait for new leader, verify AckFloor matches.
+ }
+
+ // -----------------------------------------------------------------------
+ // 17. TestJetStreamClusterFullConsumerState
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterFullConsumerState_ShouldHandlePurgeWithActiveConsumer()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Create R=3 stream, publish 10, pull-subscribe, fetch 1, then purge stream.
+ }
+
+ // -----------------------------------------------------------------------
+ // 18. TestJetStreamClusterMetaSnapshotsAndCatchup
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterMetaSnapshotsAndCatchup_ShouldCatchupAfterRestart()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Shut one server, create 4 streams, snapshot meta, restart server,
+ // wait for current, delete streams, restart again, verify catchup.
+ }
+
+ // -----------------------------------------------------------------------
+ // 19. TestJetStreamClusterMetaSnapshotsMultiChange
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterMetaSnapshotsMultiChange_ShouldHandleComplexDeltasOnRestart()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(2, "R3S");
+ c.WaitOnLeader();
+ // Add streams/consumers, add new server, shut it, make changes (add S3, delete S2,
+ // delete S1C1, add S1C2), snapshot, restart, verify all current.
+ }
+
+ // -----------------------------------------------------------------------
+ // 20. TestJetStreamClusterStreamSynchedTimeStamps
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterStreamSynchedTimeStamps_ShouldMaintainTimestampAfterLeaderChange()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Publish to R=3 memory stream, record timestamp, kill stream leader,
+ // fetch msg from new leader, verify timestamps match.
+ }
+
+ // -----------------------------------------------------------------------
+ // 21. TestJetStreamClusterRestoreSingleConsumer
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterRestoreSingleConsumer_ShouldRestoreAfterFullClusterRestart()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Create stream, publish, subscribe durable, ack, stop all, restart all,
+ // verify stream and consumer are restored.
+ }
+
+ // -----------------------------------------------------------------------
+ // 22. TestJetStreamClusterMaxBytesForStream
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterMaxBytesForStream_ShouldEnforcePerServerStorageLimit()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Create R=2 stream with MaxBytes=2GB (ok), then try 4GB (should fail: no suitable peers).
+ }
+
+ // -----------------------------------------------------------------------
+ // 23. TestJetStreamClusterStreamPublishWithActiveConsumers
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterStreamPublishWithActiveConsumers_ShouldDeliverInOrderAfterLeaderChange()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Create R=3 stream, subscribe durable, publish 10 in sequence, verify order,
+ // kill consumer leader, publish 10 more, verify order continues.
+ }
+
+ // -----------------------------------------------------------------------
+ // 24. TestJetStreamClusterStreamOverlapSubjects
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterStreamOverlapSubjects_ShouldPreventOverlappingSubjects()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3");
+ c.WaitOnLeader();
+ // Create TEST on "foo", try to create TEST2 on "foo" — should fail.
+ // Verify only 1 stream in list.
+ }
+
+ // -----------------------------------------------------------------------
+ // 25. TestJetStreamClusterStreamInfoList
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterStreamInfoList_ShouldReturnCorrectMsgCountsForAllStreams()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Create foo(10), bar(22), baz(33), verify StreamsInfo returns correct counts.
+ }
+
+ // -----------------------------------------------------------------------
+ // 26. TestJetStreamClusterConsumerInfoList
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterConsumerInfoList_ShouldReturnCorrectConsumerStates()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Create R=3 stream, publish 10, create 3 pull consumers with different
+ // fetch/ack combos, verify ConsumersInfo returns correct delivered/ackfloor.
+ }
+
+ // -----------------------------------------------------------------------
+ // 27. TestJetStreamClusterStreamUpdate
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterStreamUpdate_ShouldUpdateMaxMsgsSuccessfully()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Create stream MaxMsgs=10, fill it, expect publish failure.
+ // Update MaxMsgs=20 from non-leader, verify success.
+ // Attempt bad update (name mismatch), verify only 1 response.
+ }
+
+ // -----------------------------------------------------------------------
+ // 28. TestJetStreamClusterStreamExtendedUpdates
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterStreamExtendedUpdates_ShouldAllowSubjectUpdateButNotMirrorChange()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Subjects can be updated. Mirror changes should return JSStreamMirrorNotUpdatableError.
+ }
+
+ // -----------------------------------------------------------------------
+ // 29. TestJetStreamClusterDoubleAdd
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterDoubleAdd_ShouldBeIdempotentForStreamsAndConsumers()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(2, "R32");
+ c.WaitOnLeader();
+ // Add stream twice — should not error. Add consumer twice — should not error.
+ }
+
+ // -----------------------------------------------------------------------
+ // 30. TestJetStreamClusterDefaultMaxAckPending
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterDefaultMaxAckPending_ShouldSetDefaultAckPendingOnConsumer()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(2, "R32");
+ c.WaitOnLeader();
+ // Create consumer with default config, verify MaxAckPending == JsDefaultMaxAckPending (20000).
+ }
+
+ // -----------------------------------------------------------------------
+ // 31. TestJetStreamClusterStreamNormalCatchup
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterStreamNormalCatchup_ShouldCatchupAfterRejoiningCluster()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Publish 10 msgs, kill stream leader, publish 11 more, delete one,
+ // restart old leader, wait for cluster formed + current.
+ }
+
+ // -----------------------------------------------------------------------
+ // 32. TestJetStreamClusterStreamSnapshotCatchup
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterStreamSnapshotCatchup_ShouldCatchupViaSnapshotAfterRejoining()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Publish 2, kill stream leader, publish 100, delete 2 msgs, snapshot,
+ // send more, restart old leader, wait for current, verify states match.
+ }
+
+ // -----------------------------------------------------------------------
+ // 33. TestJetStreamClusterDeleteMsg
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterDeleteMsg_ShouldDeleteMessageAndSupportPurge()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Create R=1 stream, publish 10, delete seq 1, purge stream — all should succeed.
+ }
+
+ // -----------------------------------------------------------------------
+ // 34. TestJetStreamClusterDeleteMsgAndRestart
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterDeleteMsgAndRestart_ShouldSurviveFullRestart()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Create R=2 stream, publish 10, delete seq 1, stop all, restart all,
+ // wait for stream leader.
+ }
+
+ // -----------------------------------------------------------------------
+ // 35. TestJetStreamClusterStreamSnapshotCatchupWithPurge
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterStreamSnapshotCatchupWithPurge_ShouldHandlePurgeDuringCatchup()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(5, "R5S");
+ c.WaitOnLeader();
+ // Kill stream leader, publish 10, snapshot, restart old leader,
+ // purge while recovering, wait for current, verify stream info available.
+ }
+
+ // -----------------------------------------------------------------------
+ // 36. TestJetStreamClusterExtendedStreamInfo
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterExtendedStreamInfo_ShouldIncludeClusterInfoAndReplicas()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Create R=3 stream, publish 50, verify StreamInfo contains cluster info,
+ // cluster name, leader, and 2 replicas. Replicas must be ordered.
+ // Kill leader, verify info still correct, restart, verify current.
+ }
+
+ // -----------------------------------------------------------------------
+ // 37. TestJetStreamClusterExtendedStreamInfoSingleReplica
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterExtendedStreamInfoSingleReplica_ShouldShowNoReplicasForR1Stream()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Create R=1 stream, verify cluster info shows 0 replicas.
+ // Verify ConsumersInfo returns 0 initially, 1 after adding consumer.
+ }
+
+ // -----------------------------------------------------------------------
+ // 38. TestJetStreamClusterInterestRetention
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterInterestRetention_ShouldDeleteMsgsAfterAckWithInterestPolicy()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Create Interest-retention R=3 stream, subscribe durable, publish 1, ack,
+ // verify stream goes to 0. Publish 50 more, delete consumer, verify stream goes to 0.
+ }
+
+ // -----------------------------------------------------------------------
+ // 39. TestJetStreamClusterWorkQueueRetention
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterWorkQueueRetention_ShouldRemoveMsgsAfterAckInWorkQueueMode()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Create WorkQueue R=2 stream, publish 1, pull and ack, verify stream goes to 0.
+ }
+
+ // -----------------------------------------------------------------------
+ // 40. TestJetStreamClusterMirrorAndSourceWorkQueues
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterMirrorAndSourceWorkQueues_ShouldMirrorWorkQueueMessages()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "WQ");
+ c.WaitOnLeader();
+ // Create WQ22 WorkQueue, M mirror, S source. Publish 1 to WQ22.
+ // Verify WQ22=0, M=1, S=1 (because mirror/source consume from work queue).
+ }
+
+ // -----------------------------------------------------------------------
+ // 41. TestJetStreamClusterMirrorAndSourceInterestPolicyStream
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterMirrorAndSourceInterestPolicyStream_ShouldHandleInterestPolicyWithMirrorAndSource()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "WQ");
+ c.WaitOnLeader();
+ // Create IP22 Interest stream, mirror M, source S.
+ // Without other interest: IP22=0, M=1, S=1.
+ // After adding subscriber: IP22=1, M=2, S=2.
+ }
+
+ // -----------------------------------------------------------------------
+ // 42. TestJetStreamClusterInterestRetentionWithFilteredConsumers
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterInterestRetentionWithFilteredConsumers_ShouldTrackPerFilteredConsumer()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Create Interest stream on "*", two filtered consumers (foo, bar).
+ // Verify messages are retained until all consumers ack.
+ // Delete consumers, verify stream goes to 0.
+ // Test same with pull consumer.
+ }
+
+ // -----------------------------------------------------------------------
+ // 43. TestJetStreamClusterEphemeralConsumerNoImmediateInterest
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterEphemeralConsumerNoImmediateInterest_ShouldCleanUpWithoutActiveSubscriber()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Create ephemeral consumer with deliver subject "r", set inactive threshold to 500ms,
+ // verify consumer disappears within 5s.
+ }
+
+ // -----------------------------------------------------------------------
+ // 44. TestJetStreamClusterEphemeralConsumerCleanup
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterEphemeralConsumerCleanup_ShouldRemoveConsumerOnUnsubscribe()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Create R=2 stream, subscribe (ephemeral), set inactive threshold to 10ms,
+ // verify 1 consumer. Unsubscribe, verify consumer removed within 2s.
+ }
+
+ // -----------------------------------------------------------------------
+ // 45. TestJetStreamClusterEphemeralConsumersNotReplicated
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterEphemeralConsumersNotReplicated_ShouldBeR1Only()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Create R=3 stream, ephemeral subscribe, verify consumer cluster has 0 replicas (R=1).
+ // Shut consumer server, verify optimistic delivery may fail (logged, not fatal).
+ }
+
+ // -----------------------------------------------------------------------
+ // 46. TestJetStreamClusterUserSnapshotAndRestore
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterUserSnapshotAndRestore_ShouldRestoreStreamWithConsumerState()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Create R=2 stream, publish 200, create 2 consumers with partial ack state,
+ // snapshot, delete stream, restore, verify message count and consumer state.
+ }
+
+ // -----------------------------------------------------------------------
+ // 47. TestJetStreamClusterUserSnapshotAndRestoreConfigChanges
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterUserSnapshotAndRestoreConfigChanges_ShouldAllowConfigChangesOnRestore()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Snapshot R=2 stream, delete it, restore with different subjects/storage/replicas.
+ }
+
+ // -----------------------------------------------------------------------
+ // 48. TestJetStreamClusterAccountInfoAndLimits
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterAccountInfoAndLimits_ShouldEnforceStreamAndConsumerLimits()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(5, "R5S");
+ c.WaitOnLeader();
+ // Set limits: 1024 mem, 8000 store, 3 streams, 2 consumers.
+ // Create 3 streams, verify 4th fails. Verify store enforcement.
+ // Create 2 consumers (with idempotent create), verify 3rd fails.
+ }
+
+ // -----------------------------------------------------------------------
+ // 49. TestJetStreamClusterMaxStreamsReached
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterMaxStreamsReached_ShouldAllowIdempotentCreateUnderLimit()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // MaxStreams=1: 15 parallel creates of same stream — all succeed (idempotent).
+ // MaxStreams=2, 2 existing streams: 15 parallel creates alternating — all succeed.
+ }
+
+ // -----------------------------------------------------------------------
+ // 50. TestJetStreamClusterStreamLimits
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterStreamLimits_ShouldEnforceMaxMsgSizeAndMaxMsgsAndMaxAge()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // R=5 fails on 3-node. R=3 stream with MaxMsgSize=11, MaxMsgs=5, MaxAge=250ms, DiscardNew.
+ // Large msg fails, 5 msgs ok, 6th fails. After age expires, msgs=0, publish succeeds.
+ }
+
+ // -----------------------------------------------------------------------
+ // 51. TestJetStreamClusterStreamInterestOnlyPolicy
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterStreamInterestOnlyPolicy_ShouldNotRetainMsgsWithoutInterest()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Publish 10 without consumer → stream stays at 0.
+ // Add consumer, publish 10 → stream has 10. Delete consumer → stream goes to 0.
+ }
+
+ // -----------------------------------------------------------------------
+ // 52. TestJetStreamClusterExtendedAccountInfo
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterExtendedAccountInfo_ShouldTrackStreamsConsumersAndApiErrors()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Create 3 streams with consumers, verify AccountInfo shows 3 streams, 3 consumers, >=7 API calls.
+ // Make 4 bad API calls, verify Errors==4.
+ }
+
+ // -----------------------------------------------------------------------
+ // 53. TestJetStreamClusterPeerRemovalAPI
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterPeerRemovalApi_ShouldRemovePeerViaApi()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(5, "R5S");
+ c.WaitOnLeader();
+ // Unknown peer removal → error. Valid peer removal → success + advisory published.
+ // Verify peer removed from cluster peers within 5s.
+ }
+
+ // -----------------------------------------------------------------------
+ // 54. TestJetStreamClusterPeerRemovalAndStreamReassignment
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterPeerRemovalAndStreamReassignment_ShouldReassignStreamAfterPeerRemoval()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(5, "R5S");
+ c.WaitOnLeader();
+ // Create R=3 stream, remove one non-leader stream peer via API,
+ // verify stream still has 2 current replicas (none is the removed server).
+ }
+
+ // -----------------------------------------------------------------------
+ // 55. TestJetStreamClusterPeerRemovalAndStreamReassignmentWithoutSpace
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterPeerRemovalAndStreamReassignmentWithoutSpace_ShouldHandleInsufficientPeers()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // R=3 stream in 3-node cluster, remove one peer — cluster goes to 2 nodes.
+ // Stream should scale down to R=2 (no space for R=3).
+ }
+
+ // -----------------------------------------------------------------------
+ // 56. TestJetStreamClusterPeerRemovalAndServerBroughtBack
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterPeerRemovalAndServerBroughtBack_ShouldHandleServerReintroduction()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Remove server from cluster, bring it back, verify peer count restored to 3.
+ }
+
+ // -----------------------------------------------------------------------
+ // 57. TestJetStreamClusterPeerExclusionTag
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterPeerExclusionTag_ShouldExcludeTaggedPeersFromPlacement()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Stream with placement excluding a tag should not place on tagged server.
+ }
+
+ // -----------------------------------------------------------------------
+ // 58. TestJetStreamClusterAccountPurge
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterAccountPurge_ShouldDeleteAllStreamsAndConsumersForAccount()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Create several streams with consumers, purge account via $JS.API.ACCOUNT.PURGE,
+ // verify all streams/consumers removed.
+ }
+
+ // -----------------------------------------------------------------------
+ // 59. TestJetStreamClusterScaleConsumer
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterScaleConsumer_ShouldScaleConsumerReplicasUpAndDown()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "C");
+ c.WaitOnLeader();
+ // Create R=3 stream + durable consumer, publish 1000 msgs,
+ // scale consumer down to 1, up to 3, down to 1, up to 0 (inherit from stream),
+ // consuming one msg between each scale, verify state consistency throughout.
+ }
+
+ // -----------------------------------------------------------------------
+ // 60. TestJetStreamClusterConsumerScaleUp
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterConsumerScaleUp_ShouldMaintainConsumerLeadershipAfterStreamScaleUp()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "HUB");
+ c.WaitOnLeader();
+ // Create R=1 stream + durable R=0 consumer, publish 100 msgs,
+ // scale stream to R=2, wait 2s, verify consumer leader still present.
+ }
+
+ // -----------------------------------------------------------------------
+ // 61. TestJetStreamClusterPeerOffline
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterPeerOffline_ShouldMarkServerOfflineAndOnlineCorrectly()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(5, "R5S");
+ c.WaitOnLeader();
+ // Shut a non-leader, verify it shows as offline. Restart it, verify online again.
+ }
+
+ // -----------------------------------------------------------------------
+ // 62. TestJetStreamClusterNoQuorumStepdown
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterNoQuorumStepdown_ShouldStepDownLeaderWhenQuorumLost()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Shut 2 of 3 servers, verify meta leader steps down (no quorum).
+ }
+
+ // -----------------------------------------------------------------------
+ // 63. TestJetStreamClusterCreateResponseAdvisoriesHaveSubject
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterCreateResponseAdvisoriesHaveSubject_ShouldIncludeSubjectInAdvisories()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Subscribe to $JS.EVENT.ADVISORY.API.>, create stream, verify advisory has subject field set.
+ }
+
+ // -----------------------------------------------------------------------
+ // 64. TestJetStreamClusterRestartAndRemoveAdvisories
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterRestartAndRemoveAdvisories_ShouldNotSendAdvisoriesForRemovedOnRestart()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Create/delete streams, restart cluster, verify no spurious create/delete advisories on restart.
+ }
+
+ // -----------------------------------------------------------------------
+ // 65. TestJetStreamClusterNoDuplicateOnNodeRestart
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterNoDuplicateOnNodeRestart_ShouldNotDeliverDuplicateMessagesOnRestart()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Subscribe sync, publish, receive, restart node, verify no duplicate delivery.
+ }
+
+ // -----------------------------------------------------------------------
+ // 66. TestJetStreamClusterNoDupePeerSelection
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterNoDupePeerSelection_ShouldNotSelectSamePeerTwiceForConsumer()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Create R=3 stream, create R=3 consumer, verify consumer cluster has distinct peers.
+ }
+
+ // -----------------------------------------------------------------------
+ // 67. TestJetStreamClusterStreamRemovePeer
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterStreamRemovePeer_ShouldReassignStreamAfterPeerRemoval()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(5, "R5S");
+ c.WaitOnLeader();
+ // Remove stream peer via $JS.API.STREAM.PEER.REMOVE, verify stream reassigned to new peer.
+ }
+
+ // -----------------------------------------------------------------------
+ // 68. TestJetStreamClusterStreamLeaderStepDown
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterStreamLeaderStepDown_ShouldElectNewStreamLeaderAfterStepDown()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Step down stream leader, verify new leader elected and stream still accessible.
+ }
+
+ // -----------------------------------------------------------------------
+ // 69. TestJetStreamClusterRemoveServer
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterRemoveServer_ShouldRebalanceStreamsAfterServerRemoval()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(5, "R5S");
+ c.WaitOnLeader();
+ // Remove server, verify streams are rebalanced, no stale peer references remain.
+ }
+
+ // -----------------------------------------------------------------------
+ // 70. TestJetStreamClusterPurgeReplayAfterRestart
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterPurgeReplayAfterRestart_ShouldReplayPurgeAfterRestart()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Publish 10, purge, restart cluster, verify stream is still empty.
+ }
+
+ // -----------------------------------------------------------------------
+ // 71. TestJetStreamClusterStreamGetMsg
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterStreamGetMsg_ShouldGetMessageBySequenceFromCluster()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Publish a msg, get it via $JS.API.STREAM.MSG.GET, verify data matches.
+ }
+
+ // -----------------------------------------------------------------------
+ // 72. TestJetStreamClusterStreamDirectGetMsg
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterStreamDirectGetMsg_ShouldSupportDirectGetFromReplica()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Create R=3 stream with AllowDirect=true, publish, direct-get from replica.
+ }
+
+ // -----------------------------------------------------------------------
+ // 73. TestJetStreamClusterStreamPerf
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterStreamPerf_ShouldPublishAndReceiveAllMessagesWithinTimeout()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Publish 5000 msgs to R=3 stream, verify all received by pull consumer.
+ }
+
+ // -----------------------------------------------------------------------
+ // 74. TestJetStreamClusterConsumerPerf
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterConsumerPerf_ShouldDeliverAllMessagesToPushConsumer()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Publish 5000 msgs to R=3 stream, push-consume all, verify count.
+ }
+
+ // -----------------------------------------------------------------------
+ // 75. TestJetStreamClusterQueueSubConsumer
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterQueueSubConsumer_ShouldDeliverExactlyOnceAcrossQueueGroup()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Create stream, subscribe with queue group, publish 100 msgs,
+ // verify each msg delivered exactly once across all queue members.
+ }
+
+ // -----------------------------------------------------------------------
+ // 76. TestJetStreamClusterLeaderStepdown
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterLeaderStepdown_ShouldElectNewMetaLeaderAfterStepDown()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Request meta leader stepdown, verify new leader elected.
+ }
+
+ // -----------------------------------------------------------------------
+ // 77. TestJetStreamClusterSourcesFilteringAndUpdating
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterSourcesFilteringAndUpdating_ShouldFilterSourcesBySubjectAndSupportUpdate()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Create source stream, create stream with filtered source, verify filtering,
+ // update source filter, verify updated behavior.
+ }
+
+ // -----------------------------------------------------------------------
+ // 78. TestJetStreamClusterSourcesUpdateOriginError
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterSourcesUpdateOriginError_ShouldReportErrorWhenSourceOriginChanges()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Create stream with source, update to change source origin — should error.
+ }
+
+ // -----------------------------------------------------------------------
+ // 79. TestJetStreamClusterMirrorAndSourcesClusterRestart
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterMirrorAndSourcesClusterRestart_ShouldContinueAfterRestart()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Create mirror and source streams, publish, restart cluster, verify counts preserved.
+ }
+
+ // -----------------------------------------------------------------------
+ // 80. TestJetStreamClusterMirrorAndSourcesFilteredConsumers
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterMirrorAndSourcesFilteredConsumers_ShouldWorkWithFilteredConsumers()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Create mirror with filtered subjects, consume from mirror with consumer filter.
+ }
+
+ // -----------------------------------------------------------------------
+ // 81. TestJetStreamClusterCrossAccountMirrorsAndSources
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterCrossAccountMirrorsAndSources_ShouldMirrorAcrossAccounts()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamClusterWithTemplate(ConfigHelper.JsClusterAccountsTemplate, 3, "R3S");
+ c.WaitOnLeader();
+ // Create stream in account ONE, mirror in account TWO, verify mirror receives msgs.
+ }
+
+ // -----------------------------------------------------------------------
+ // 82. TestJetStreamClusterFailMirrorsAndSources
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterFailMirrorsAndSources_ShouldFailGracefullyOnInvalidMirrorOrSource()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Attempt to create mirror/source on non-existent stream — should get error response.
+ }
+
+ // -----------------------------------------------------------------------
+ // 83. TestJetStreamClusterConsumerDeliveredSyncReporting
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterConsumerDeliveredSyncReporting_ShouldReportDeliveredSequenceAccurately()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Push consumer, publish msgs, verify Delivered.Stream and Delivered.Consumer in sync.
+ }
+
+ // -----------------------------------------------------------------------
+ // 84. TestJetStreamClusterConsumerAckSyncReporting
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterConsumerAckSyncReporting_ShouldReportAckFloorAccurately()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Pull consumer, fetch and ack, verify AckFloor.Stream and AckFloor.Consumer in sync.
+ }
+
+ // -----------------------------------------------------------------------
+ // 85. TestJetStreamClusterConsumerDeleteInterestPolicyMultipleConsumers
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterConsumerDeleteInterestPolicyMultipleConsumers_ShouldNotPurgeMsgsWithOtherActiveConsumers()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Interest stream, 2 consumers. Delete one — msgs should remain until other acks too.
+ }
+
+ // -----------------------------------------------------------------------
+ // 86. TestJetStreamClusterConsumerAckNoneInterestPolicyShouldNotRetainAfterDelivery
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterConsumerAckNoneInterestPolicyShouldNotRetainAfterDelivery_ShouldRemoveMsgsOnDelivery()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // AckNone consumer on Interest stream: msgs removed on delivery without explicit ack.
+ }
+
+ // -----------------------------------------------------------------------
+ // 87. TestJetStreamClusterConsumerDeleteAckNoneInterestPolicyWithOthers
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterConsumerDeleteAckNoneInterestPolicyWithOthers_ShouldHandleDeleteWithMultipleConsumers()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // AckNone + AckExplicit consumers on Interest stream, delete AckNone consumer,
+ // verify explicit consumer still sees msgs.
+ }
+
+ // -----------------------------------------------------------------------
+ // 88. TestJetStreamClusterMetaStepdownFromNonSysAccount
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterMetaStepdownFromNonSysAccount_ShouldFailWithPermissionError()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Non-system account attempting meta stepdown should get an error.
+ }
+
+ // -----------------------------------------------------------------------
+ // 89. TestJetStreamClusterMaxDeliveriesOnInterestStreams
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterMaxDeliveriesOnInterestStreams_ShouldRespectMaxDeliveriesSetting()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Interest stream, consumer MaxDelivers=3, verify msg removed after 3 delivery attempts.
+ }
+
+ // -----------------------------------------------------------------------
+ // 90. TestJetStreamClusterMetaRecoveryUpdatesDeletesConsumers
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterMetaRecoveryUpdatesDeletesConsumers_ShouldRecoverUpdatedAndDeletedConsumers()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Create, update, delete consumer. Restart. Verify correct final state recovered.
+ }
+
+ // -----------------------------------------------------------------------
+ // 91. TestJetStreamClusterMetaRecoveryRecreateFileStreamAsMemory
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterMetaRecoveryRecreateFileStreamAsMemory_ShouldRecoverStreamWithChangedStorageType()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Create File stream, delete it, recreate as Memory, restart, verify Memory type recovered.
+ }
+
+ // -----------------------------------------------------------------------
+ // 92. TestJetStreamClusterMetaRecoveryConsumerCreateAndRemove
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterMetaRecoveryConsumerCreateAndRemove_ShouldRecoverAfterConsumerCreateAndDelete()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Create consumer, delete it, restart, verify consumer is not present.
+ }
+
+ // -----------------------------------------------------------------------
+ // 93. TestJetStreamClusterMetaRecoveryAddAndUpdateStream
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterMetaRecoveryAddAndUpdateStream_ShouldRecoverUpdatedStreamConfig()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Create stream, update MaxMsgs, restart, verify updated config recovered.
+ }
+
+ // -----------------------------------------------------------------------
+ // 94. TestJetStreamClusterConsumerAckOutOfBounds
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterConsumerAckOutOfBounds_ShouldHandleOutOfBoundsAckGracefully()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Ack a sequence beyond delivered range — server should not crash, consumer stays healthy.
+ }
+
+ // -----------------------------------------------------------------------
+ // 95. TestJetStreamClusterCatchupLoadNextMsgTooManyDeletes
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterCatchupLoadNextMsgTooManyDeletes_ShouldCatchupWithHighDensityDeletes()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Publish 1000 msgs, delete 999 of them, kill stream leader, restart, verify catchup.
+ }
+
+ // -----------------------------------------------------------------------
+ // 96. TestJetStreamClusterCatchupMustStallWhenBehindOnApplies
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterCatchupMustStallWhenBehindOnApplies_ShouldNotOverloadCatchupQueue()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Kill stream replica, flood with messages, restart replica, verify catchup without queue overflow.
+ }
+
+ // -----------------------------------------------------------------------
+ // 97. TestJetStreamClusterConsumerInfoAfterCreate
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterConsumerInfoAfterCreate_ShouldReturnConsumerInfoImmediatelyAfterCreate()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Create consumer, immediately request ConsumerInfo, verify info is available.
+ }
+
+ // -----------------------------------------------------------------------
+ // 98. TestJetStreamClusterStreamUpscalePeersAfterDownscale
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterStreamUpscalePeersAfterDownscale_ShouldRestoreAllPeersOnUpscale()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(5, "R5S");
+ c.WaitOnLeader();
+ // Scale stream from R=3 to R=1, then back to R=3, verify 3 distinct current peers.
+ }
+
+ // -----------------------------------------------------------------------
+ // 99. TestJetStreamClusterClearAllPreAcksOnRemoveMsg
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterClearAllPreAcksOnRemoveMsg_ShouldClearPreAcksWhenMessageRemoved()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Interest stream, pre-ack msg, then delete it via DeleteMsg, verify pre-ack state cleared.
+ }
+
+ // -----------------------------------------------------------------------
+ // 100. TestJetStreamClusterStreamHealthCheckMustNotRecreate
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterStreamHealthCheckMustNotRecreate_ShouldNotRecreateExistingStream()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Health check on existing stream must not trigger recreation or data loss.
+ }
+
+ // -----------------------------------------------------------------------
+ // 101. TestJetStreamClusterStreamHealthCheckMustNotDeleteEarly
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterStreamHealthCheckMustNotDeleteEarly_ShouldNotDeleteStreamDuringHealthCheck()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Health check on stream with messages must not trigger premature deletion.
+ }
+
+ // -----------------------------------------------------------------------
+ // 102. TestJetStreamClusterStreamHealthCheckOnlyReportsSkew
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterStreamHealthCheckOnlyReportsSkew_ShouldOnlyReportSkewNotForceRecovery()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Force skew in stream replica, health check should report skew, not force recreation.
+ }
+
+ // -----------------------------------------------------------------------
+ // 103. TestJetStreamClusterStreamHealthCheckStreamCatchup
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterStreamHealthCheckStreamCatchup_ShouldTriggerCatchupOnHealthCheckFailure()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Simulate replica behind, health check should trigger catchup.
+ }
+
+ // -----------------------------------------------------------------------
+ // 104. TestJetStreamClusterConsumerHealthCheckMustNotRecreate
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterConsumerHealthCheckMustNotRecreate_ShouldNotRecreateExistingConsumer()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Health check on existing consumer must not trigger recreation.
+ }
+
+ // -----------------------------------------------------------------------
+ // 105. TestJetStreamClusterConsumerHealthCheckMustNotDeleteEarly
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterConsumerHealthCheckMustNotDeleteEarly_ShouldNotDeleteActiveConsumer()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Active consumer must not be prematurely deleted by health check.
+ }
+
+ // -----------------------------------------------------------------------
+ // 106. TestJetStreamClusterConsumerHealthCheckOnlyReportsSkew
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterConsumerHealthCheckOnlyReportsSkew_ShouldNotForceRecreateOnSkew()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Skewed consumer state should be reported, not cause forced recreation.
+ }
+
+ // -----------------------------------------------------------------------
+ // 107. TestJetStreamClusterConsumerHealthCheckDeleted
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterConsumerHealthCheckDeleted_ShouldCleanUpDeletedConsumerOnHealthCheck()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Deleted consumer should be cleaned up gracefully during health check.
+ }
+
+ // -----------------------------------------------------------------------
+ // 108. TestJetStreamClusterRespectConsumerStartSeq
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterRespectConsumerStartSeq_ShouldStartDeliveryFromConfiguredSequence()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Create consumer with DeliverByStartSequence=5, verify first delivered msg is seq 5.
+ }
+
+ // -----------------------------------------------------------------------
+ // 109. TestJetStreamClusterPeerRemoveStreamConsumerDesync
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterPeerRemoveStreamConsumerDesync_ShouldNotDesyncConsumerAfterPeerRemoval()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(5, "R5S");
+ c.WaitOnLeader();
+ // Remove a peer from stream, verify consumer state remains in sync with stream.
+ }
+
+ // -----------------------------------------------------------------------
+ // 110. TestJetStreamClusterStuckConsumerAfterLeaderChangeWithUnknownDeliveries
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterStuckConsumerAfterLeaderChangeWithUnknownDeliveries_ShouldRecoverFromStuckState()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Consumer with in-flight msgs, leader change — consumer should recover without getting stuck.
+ }
+
+ // -----------------------------------------------------------------------
+ // 111. TestJetStreamClusterAccountStatsForReplicatedStreams
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterAccountStatsForReplicatedStreams_ShouldCountStorageOnceNotPerReplica()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Publish to R=3 stream, verify account stats count storage once (logical), not 3x.
+ }
+
+ // -----------------------------------------------------------------------
+ // 112. TestJetStreamClusterRecreateConsumerFromMetaSnapshot
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterRecreateConsumerFromMetaSnapshot_ShouldRecreateConsumerFromSnapshot()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Create consumer, snapshot meta, shut server, restore from snapshot, verify consumer exists.
+ }
+
+ // -----------------------------------------------------------------------
+ // 113. TestJetStreamClusterUpgradeStreamVersioning
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterUpgradeStreamVersioning_ShouldHandleStreamVersionUpgrade()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Simulate stream version upgrade scenario, verify stream accessible after upgrade.
+ }
+
+ // -----------------------------------------------------------------------
+ // 114. TestJetStreamClusterUpgradeConsumerVersioning
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterUpgradeConsumerVersioning_ShouldHandleConsumerVersionUpgrade()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Simulate consumer version upgrade, verify consumer accessible after upgrade.
+ }
+
+ // -----------------------------------------------------------------------
+ // 115. TestJetStreamClusterInterestPolicyAckAll
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterInterestPolicyAckAll_ShouldRemoveMsgOnlyAfterAllConsumersAckAll()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Interest stream, AckAll consumer: msg removed only after all consumers AckAll.
+ }
+
+ // -----------------------------------------------------------------------
+ // 116. TestJetStreamClusterPreserveRedeliveredWithLaggingStream
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterPreserveRedeliveredWithLaggingStream_ShouldPreserveRedeliveredFlagDuringLag()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Consumer with lagging stream: redelivered flag must be preserved across leader changes.
+ }
+
+ // -----------------------------------------------------------------------
+ // 117. TestJetStreamClusterInvalidJSACKOverRoute
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterInvalidJsAckOverRoute_ShouldHandleInvalidAckGracefully()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // Invalid JSACK sent over a route should not crash the server.
+ }
+
+ // -----------------------------------------------------------------------
+ // 118. TestJetStreamClusterConsumerOnlyDeliverMsgAfterQuorum
+ // -----------------------------------------------------------------------
+ [SkippableFact]
+ public void ClusterConsumerOnlyDeliverMsgAfterQuorum_ShouldNotDeliverBeforeQuorumAchieved()
+ {
+ Skip.If(ShouldSkip(), "Cluster integration tests are not enabled.");
+
+ using var c = TestCluster.CreateJetStreamCluster(3, "R3S");
+ c.WaitOnLeader();
+ // R=3 consumer must not deliver msg until quorum (2 of 3) of replicas have acknowledged the entry.
+ }
+}
diff --git a/dotnet/tests/ZB.MOM.NatsNet.Server.IntegrationTests/ZB.MOM.NatsNet.Server.IntegrationTests.csproj b/dotnet/tests/ZB.MOM.NatsNet.Server.IntegrationTests/ZB.MOM.NatsNet.Server.IntegrationTests.csproj
index e48edff..2777913 100644
--- a/dotnet/tests/ZB.MOM.NatsNet.Server.IntegrationTests/ZB.MOM.NatsNet.Server.IntegrationTests.csproj
+++ b/dotnet/tests/ZB.MOM.NatsNet.Server.IntegrationTests/ZB.MOM.NatsNet.Server.IntegrationTests.csproj
@@ -17,7 +17,9 @@
+
+
@@ -25,6 +27,8 @@
+
+
diff --git a/reports/current.md b/reports/current.md
index a163a75..dab6885 100644
--- a/reports/current.md
+++ b/reports/current.md
@@ -1,6 +1,6 @@
# NATS .NET Porting Status Report
-Generated: 2026-03-01 16:08:14 UTC
+Generated: 2026-03-01 17:16:29 UTC
## Modules (12 total)