diff --git a/src/NATS.Server/JetStream/Consumers/PushConsumerEngine.cs b/src/NATS.Server/JetStream/Consumers/PushConsumerEngine.cs
index 735a59b..0425dc0 100644
--- a/src/NATS.Server/JetStream/Consumers/PushConsumerEngine.cs
+++ b/src/NATS.Server/JetStream/Consumers/PushConsumerEngine.cs
@@ -57,4 +57,11 @@ public sealed class PushFrame
public bool IsHeartbeat { get; init; }
public StoredMessage? Message { get; init; }
public DateTime AvailableAtUtc { get; init; } = DateTime.UtcNow;
+
+ ///
+ /// The NATS subject of the delivered message. Populated for data frames;
+ /// empty string for heartbeat and flow-control frames.
+ /// Mirrors the Go server's deliver-subject routing (consumer.go).
+ ///
+ public string Subject => Message?.Subject ?? string.Empty;
}
diff --git a/tests/NATS.Server.Tests/JetStream/Storage/FileStorePermutationTests.cs b/tests/NATS.Server.Tests/JetStream/Storage/FileStorePermutationTests.cs
new file mode 100644
index 0000000..a98280f
--- /dev/null
+++ b/tests/NATS.Server.Tests/JetStream/Storage/FileStorePermutationTests.cs
@@ -0,0 +1,930 @@
+// Reference: golang/nats-server/server/filestore_test.go
+// Go's testFileStoreAllPermutations (line 55) runs every test across 6 combinations:
+// {NoCipher, ChaCha, AES} x {NoCompression, S2Compression}
+// This file ports 16 representative tests from that matrix to .NET using
+// [Theory] + [MemberData] so each test case executes all 6 permutations
+// automatically, giving ~96 total executions.
+//
+// Covered Go tests (each appears 6 times):
+// TestFileStoreBasics (line 86)
+// TestFileStoreMsgHeaders (line 152)
+// TestFileStoreBasicWriteMsgsAndRestore (line 181)
+// TestFileStoreSelectNextFirst (line 304)
+// TestFileStoreMsgLimit (line 484)
+// TestFileStoreMsgLimitBug (line 518)
+// TestFileStoreBytesLimit (line 537)
+// TestFileStoreAgeLimit (line 616)
+// TestFileStoreTimeStamps (line 683)
+// TestFileStorePurge (line 710)
+// TestFileStoreCollapseDmap (line 1561)
+// TestFileStoreWriteAndReadSameBlock (line 1510)
+// TestFileStoreAndRetrieveMultiBlock (line 1527)
+// TestFileStoreSnapshot (line 1799)
+// TestFileStoreBasics (large payload variant)
+// TestFileStoreBasics (sequential ordering variant)
+
+using System.Text;
+using NATS.Server.JetStream.Storage;
+
+namespace NATS.Server.Tests.JetStream.Storage;
+
+public sealed class FileStorePermutationTests : IDisposable
+{
+ private readonly string _dir;
+
+ public FileStorePermutationTests()
+ {
+ _dir = Path.Combine(Path.GetTempPath(), $"nats-js-fs-perm-{Guid.NewGuid():N}");
+ Directory.CreateDirectory(_dir);
+ }
+
+ public void Dispose()
+ {
+ if (Directory.Exists(_dir))
+ Directory.Delete(_dir, recursive: true);
+ }
+
+ // -------------------------------------------------------------------------
+ // Permutation matrix: {NoCipher, ChaCha, Aes} x {NoCompression, S2Compression}
+ // Mirrors Go's testFileStoreAllPermutations (filestore_test.go:55).
+ // -------------------------------------------------------------------------
+
+ public static IEnumerable