diff --git a/docs/plans/2026-02-24-remaining-parity-plan.md b/docs/plans/2026-02-24-remaining-parity-plan.md new file mode 100644 index 0000000..6da9efd --- /dev/null +++ b/docs/plans/2026-02-24-remaining-parity-plan.md @@ -0,0 +1,1320 @@ +# Remaining Go Parity Implementation Plan + +> **For Claude:** REQUIRED SUB-SKILL: Use superpowers-extended-cc:executing-plans to implement this plan task-by-task. + +**Goal:** Port ~1,418 unmapped Go tests to .NET, building/enhancing features as needed. Mark ~224 Go-specific tests as not_applicable. Target: 90%+ Go test mapping. + +**Architecture:** Feature-first by gap severity across 8 parallel tracks. Each task: enhance .NET feature → port Go tests → update test_parity.db → commit. Targeted test runs only (`dotnet test --filter`); full suite at end. + +**Tech Stack:** .NET 10 / C# 14, xUnit 3, Shouldly, NSubstitute, SQLite (test_parity.db) + +--- + +## Conventions + +- **Assertions**: Shouldly only (`value.ShouldBe(expected)`, `action.ShouldThrow()`) +- **Go reference**: Each ported test gets a comment: `// Go: TestName (file.go:line)` +- **Test run**: `dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~ClassName" -v minimal` +- **DB update**: `sqlite3 docs/test_parity.db "UPDATE go_tests SET status='mapped', dotnet_test='DotNetName', dotnet_file='TestFile.cs' WHERE go_test='GoTestName' AND go_file='go_file.go'"` +- **Commit**: After each task, commit with `test(parity): + DB update` + +--- + +## Task 0: Mark Not-Applicable Tests in DB + +**Files:** +- Modify: `docs/test_parity.db` + +**Step 1: Mark norace tests (126)** + +```bash +sqlite3 docs/test_parity.db "UPDATE go_tests SET status='not_applicable', notes='Stress test requiring real multi-server infrastructure' WHERE go_file IN ('norace_1_test.go','norace_2_test.go') AND status='unmapped'" +``` + +**Step 2: Mark platform-specific tests (23)** + +```bash +sqlite3 docs/test_parity.db "UPDATE go_tests SET status='not_applicable', notes='Platform-specific: not applicable to .NET' WHERE go_file IN ('signal_test.go','certstore_windows_test.go','service_windows_test.go','service_test.go') AND status='unmapped'" +``` + +**Step 3: Mark Go-specific data structure tests (38)** + +```bash +sqlite3 docs/test_parity.db "UPDATE go_tests SET status='not_applicable', notes='Go-specific data structure/mechanism' WHERE go_file IN ('dirstore_test.go','ipqueue_test.go','split_test.go','ring_test.go') AND status='unmapped'" +``` + +**Step 4: Mark performance/benchmark tests (35)** + +```bash +sqlite3 docs/test_parity.db "UPDATE go_tests SET status='not_applicable', notes='Go performance benchmark, not functional test' WHERE status='unmapped' AND (go_test LIKE '%Perf%' OR go_test LIKE '%Bench%')" +``` + +**Step 5: Verify counts** + +```bash +sqlite3 docs/test_parity.db "SELECT status, COUNT(*) FROM go_tests GROUP BY status" +``` + +Expected: not_applicable count increases by ~222. + +**Step 6: Commit** + +```bash +git add docs/test_parity.db +git commit -m "chore: mark ~222 Go tests as not_applicable in parity DB" +``` + +--- + +## Track 1: Storage Engine (167 tests) + +### Task 1: FileStore Block Recovery & Compaction (~50 tests) + +**Gaps addressed:** Gap 1 — CRITICAL + +**Files:** +- Modify: `src/NATS.Server/JetStream/Storage/FileStore.cs` +- Modify: `src/NATS.Server/JetStream/Storage/MsgBlock.cs` +- Create: `tests/NATS.Server.Tests/JetStream/Storage/FileStoreRecoveryTests.cs` +- Modify: `docs/test_parity.db` + +**Feature work:** +1. Add `RecoverFullState()` to FileStore — deserialize binary state file, validate checksums, reconstruct block metadata. Go ref: `filestore.go:1754` +2. Add `RebuildStateLocked()` — iterate blocks, sum messages/bytes, set FirstSeq/LastSeq. Go ref: `filestore.go:1284` +3. Enhance `Compact(seq)` — delete entire blocks below compact point, partial-block deletion with dmap update. Go ref: `filestore.go:9346` +4. Add `FlushAllPending()` — force write pending data to disk +5. Add block index rebuild on corrupt/missing index files + +**Go tests to port (~50):** +``` +TestFileStoreInvalidIndexesRebuilt +TestFileStoreRecoverFullState +TestFileStoreLargeFullState +TestFileStoreLargeFullStatePSIM +TestFileStoreMsgBlockHolesAndIndexing +TestFileStoreMsgBlockCompactionAndHoles +TestFileStoreReloadAndLoseLastSequence +TestFileStoreRestoreIndexWithMatchButLeftOverBlocks +TestFileStoreCompactAndPSIMWhenDeletingBlocks +TestFileStoreCheckSkipFirstBlockBug +TestFileStoreSelectMsgBlockBinarySearch +TestFileStoreSyncCompressOnlyIfDirty +TestFileStorePartialIndexes +TestFileStoreErrPartialLoad +TestFileStoreStreamFailToRollBug +TestFileStoreBadFirstAndFailedExpireAfterRestart +TestFileStoreSyncIntervals +TestFileStoreAsyncFlushOnSkipMsgs +TestFileStoreLeftoverSkipMsgInDmap +TestFileStoreCacheLookupOnEmptyBlock +TestFileStoreWriteFullStateHighSubjectCardinality +TestFileStoreWriteFullStateDetectCorruptState +TestFileStoreRecoverFullStateDetectCorruptState +TestFileStoreFullStateTestUserRemoveWAL +TestFileStoreFullStateTestSysRemovals +TestFileStoreTrackSubjLenForPSIM +TestFileStoreMsgBlockFirstAndLastSeqCorrupt +TestFileStoreCorruptPSIMOnDisk +TestFileStoreCorruptionSetsHbitWithoutHeaders +TestFileStoreWriteFullStateThrowsPermissionErrorIfFSModeReadOnly +TestFileStoreStoreRawMessageThrowsPermissionErrorIfFSModeReadOnly +TestFileStoreWriteFailures +TestFileStoreStreamDeleteDirNotEmpty +TestFileStoreFSSCloseAndKeepOnExpireOnRecoverBug +TestFileStoreExpireOnRecoverSubjectAccounting +TestFileStoreFSSExpireNumPendingBug +``` + +**Test command:** +```bash +dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~FileStoreRecoveryTests" -v minimal +``` + +**DB update:** Update each ported test in test_parity.db. + +**Commit:** `test(parity): port FileStore recovery & compaction tests (T1, ~50 tests) + DB update` + +--- + +### Task 2: FileStore Tombstones, Deletion & TTL (~40 tests) + +**Files:** +- Modify: `src/NATS.Server/JetStream/Storage/FileStore.cs` +- Modify: `src/NATS.Server/JetStream/Storage/MsgBlock.cs` +- Create: `tests/NATS.Server.Tests/JetStream/Storage/FileStoreTombstoneTests.cs` +- Modify: `docs/test_parity.db` + +**Feature work:** +1. Integrate `SequenceSet` (AVL) for sparse deletion tracking (dmap). Go ref: `filestore.go` dmap usage +2. Add tombstone tracking with byte accounting (`rbytes`) +3. Implement subject delete markers — mark deleted subjects for mirror/source propagation +4. Add message TTL recovery from disk state. Go ref: `filestore.go` TTL wheel persistence +5. Add message schedule encode/decode. Go ref: `filestore.go:MessageSchedule` +6. Integrate AEAD encryption into block write/read path + +**Go tests to port (~40):** +``` +TestFileStoreTombstoneRbytes +TestFileStoreTombstonesNoFirstSeqRollback +TestFileStoreTombstonesSelectNextFirstCleanup +TestFileStoreEraseMsgDoesNotLoseTombstones +TestFileStoreDetectDeleteGapWithLastSkipMsg +TestFileStoreMissingDeletesAfterCompact +TestFileStoreSubjectDeleteMarkers +TestFileStoreMessageTTLRecoveredSingleMessageWithoutStreamState +TestFileStoreMessageTTLWriteTombstone +TestFileStoreMessageTTLRecoveredOffByOne +TestFileStoreMessageScheduleEncode +TestFileStoreMessageScheduleDecode +TestFileStoreRecoverTTLAndScheduleStateAndCounters +TestFileStoreNoPanicOnRecoverTTLWithCorruptBlocks +TestFileStoreConsumerEncodeDecodeRedelivered +TestFileStoreConsumerEncodeDecodePendingBelowStreamAckFloor +TestFileStoreConsumerRedeliveredLost +TestFileStoreConsumerFlusher +TestFileStoreConsumerDeliveredUpdates +TestFileStoreConsumerDeliveredAndAckUpdates +TestFileStoreBadConsumerState +``` + +**Test command:** +```bash +dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~FileStoreTombstoneTests" -v minimal +``` + +**Commit:** `test(parity): port FileStore tombstone, TTL & consumer state tests (T2, ~40 tests) + DB update` + +--- + +### Task 3: MemStore Go-Parity Methods (~28 tests) + +**Files:** +- Modify: `src/NATS.Server/JetStream/Storage/MemStore.cs` +- Create: `tests/NATS.Server.Tests/JetStream/Storage/MemStoreGoParityTests.cs` +- Modify: `docs/test_parity.db` + +**Feature work:** +1. Add all sync Go-parity methods to MemStore: `StoreMsg`, `LoadMsg`, `LoadLastMsg`, `LoadNextMsg`, `NumPending`, `Compact`, `Truncate`, `GetSeqFromTime`, `State()`, `FastState()`, `SubjectsState()`, `SubjectsTotals()`, `FilteredState()`, `AllLastSeqs()`, `MultiLastSeqs()`, `SubjectForSeq()`, `PurgeEx()`, `SkipMsg()`, `SkipMsgs()` +2. Add per-subject tracking for subject-filtered operations +3. Add TTL/schedule support for in-memory messages +4. Add UpdateConfig for dynamic limit changes + +**Go tests to port (~28):** +``` +TestMemStoreCompact +TestMemStoreStreamStateDeleted +TestMemStoreStreamTruncate +TestMemStoreUpdateMaxMsgsPerSubject +TestMemStoreStreamCompactMultiBlockSubjectInfo +TestMemStoreSubjectsTotals +TestMemStoreNumPending +TestMemStoreMultiLastSeqs +TestMemStoreSubjectForSeq +TestMemStoreSubjectDeleteMarkers +TestMemStoreAllLastSeqs +TestMemStoreGetSeqFromTimeWithLastDeleted +TestMemStoreSkipMsgs +TestMemStoreDeleteBlocks +TestMemStoreMessageTTL +TestMemStoreMessageSchedule +TestMemStoreUpdateConfigTTLState +TestMemStoreNextWildcardMatch +TestMemStoreNextLiteralMatch +``` + +Plus remaining 9 MemStore tests from the unmapped list. + +**Test command:** +```bash +dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~MemStoreGoParityTests" -v minimal +``` + +**Commit:** `test(parity): port MemStore Go-parity methods + 28 tests (T3) + DB update` + +--- + +### Task 4: Store Interface Tests (~16 tests) + +**Files:** +- Create: `tests/NATS.Server.Tests/JetStream/Storage/StoreInterfaceTests.cs` +- Modify: `docs/test_parity.db` + +**Feature work:** Minimal — these test the IStreamStore interface contract. Both FileStore and MemStore should already implement the methods after Tasks 1-3. + +**Go tests to port (~16):** +``` +TestStoreMsgLoadNextMsgMulti +TestStoreMsgLoadPrevMsgMulti +TestStoreLoadNextMsgWildcardStartBeforeFirstMatch +TestStoreDeleteSlice +TestStoreDeleteRange +TestStoreCompactCleansUpDmap +TestStoreTruncateCleansUpDmap +TestStoreSubjectStateConsistency +TestStoreStreamInteriorDeleteAccounting +TestStoreGetSeqFromTime +TestStoreUpdateConfigTTLState +TestStorePurgeExZero +``` + +Plus remaining 4 store_test.go tests. + +**Test command:** +```bash +dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~StoreInterfaceTests" -v minimal +``` + +**Commit:** `test(parity): port store interface contract tests (T4, 16 tests) + DB update` + +--- + +## Track 2: JetStream Core API (220 tests) + +### Task 5: JetStream Mirrors, Sources & Transforms (~42 tests) + +**Gaps addressed:** Gap 3 — HIGH, Gap 7 — HIGH + +**Files:** +- Modify: `src/NATS.Server/JetStream/MirrorSource/MirrorCoordinator.cs` +- Modify: `src/NATS.Server/JetStream/MirrorSource/SourceCoordinator.cs` +- Modify: `src/NATS.Server/JetStream/StreamManager.cs` +- Create: `tests/NATS.Server.Tests/JetStream/MirrorSourceGoParityTests.cs` +- Modify: `docs/test_parity.db` + +**Feature work:** +1. Implement `MirrorCoordinator.StartSyncLoop()` — pull-based batch fetch from origin, apply to local store. Go ref: `stream.go:processMirrorMsgs` +2. Implement `SourceCoordinator.StartSyncLoop()` — consume from source with filter/transform. Go ref: `stream.go:processSourceMsgs` +3. Add subject transform integration on source consumption +4. Add dedup window maintenance (prune expired entries) +5. Add mirror/source health tracking and error state +6. Add stream republish support — re-publish on subject match. Go ref: `stream.go:republish` + +**Go tests to port (~42):** +``` +TestJetStreamMirrorStripExpectedHeaders +TestJetStreamMirroredConsumerFailAfterRestart +TestJetStreamMirrorUpdatesNotSupported +TestJetStreamMirrorFirstSeqNotSupported +TestJetStreamMirroringClipStartSeq +TestJetStreamMessageTTLWhenMirroring +TestJetStreamSubjectDeleteMarkersWithMirror +TestJetStreamPromoteMirrorDeletingOrigin +TestJetStreamPromoteMirrorUpdatingOrigin +TestJetStreamScheduledMirrorOrSource +TestJetStreamRecoverBadMirrorConfigWithSubjects +TestJetStreamSourceWorkingQueueWithLimit +TestJetStreamStreamSourceFromKV +TestJetStreamRemoveExternalSource +TestJetStreamWorkQueueSourceRestart +TestJetStreamWorkQueueSourceNamingRestart +TestJetStreamStreamUpdateWithExternalSource +TestJetStreamSourceRemovalAndReAdd +TestJetStreamAllowMsgCounterSourceAggregates +TestJetStreamAllowMsgCounterSourceVerbatim +TestJetStreamAllowMsgCounterSourceStartingAboveZero +TestJetStreamSourcingClipStartSeq +TestJetStreamInputTransform +TestJetStreamImplicitRePublishAfterSubjectTransform +TestJetStreamStreamRepublishCycle +TestJetStreamStreamRepublishOneTokenMatch +TestJetStreamStreamRepublishMultiTokenMatch +TestJetStreamStreamRepublishAnySubjectMatch +TestJetStreamStreamRepublishMultiTokenNoMatch +TestJetStreamStreamRepublishOneTokenNoMatch +TestJetStreamStreamRepublishHeadersOnly +``` + +**Test command:** +```bash +dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~MirrorSourceGoParityTests" -v minimal +``` + +**Commit:** `test(parity): port mirror, source & transform tests (T5, ~42 tests) + DB update` + +--- + +### Task 6: JetStream Storage, Recovery & Encryption (~26 tests) + +**Files:** +- Modify: `src/NATS.Server/JetStream/StreamManager.cs` +- Modify: `src/NATS.Server/JetStream/Storage/FileStore.cs` +- Create: `tests/NATS.Server.Tests/JetStream/JsStorageRecoveryTests.cs` +- Modify: `docs/test_parity.db` + +**Feature work:** +1. Add stream recovery after server restart — reload stream state from store. Go ref: `jetstream.go:recovery` +2. Add server encryption key management — per-stream key, rotation. Go ref: `jetstream.go:encryption` +3. Add direct get with time-based queries. Go ref: `jetstream_api.go:directGet` +4. Add subject delete marker generation and handling + +**Go tests to port (~26):** +``` +TestJetStreamSimpleFileRecovery +TestJetStreamStoredMsgsDontDisappearAfterCacheExpiration +TestJetStreamDeliveryAfterServerRestart +TestJetStreamStoreDirectoryFix +TestJetStreamServerEncryption +TestJetStreamServerEncryptionServerRestarts +TestJetStreamServerReencryption +TestJetStreamMessageTTLBasics +TestJetStreamMessageTTLExpiration +TestJetStreamMessageTTLInvalidConfig +TestJetStreamSubjectDeleteMarkers +TestJetStreamSubjectDeleteMarkersRestart +TestJetStreamDirectGetUpToTime +TestJetStreamDirectGetStartTimeSingleMsg +TestJetStreamFileStoreFirstSeqAfterRestart +TestJetStreamLargeExpiresAndServerRestart +TestJetStreamExpireCausesDeadlock +TestJetStreamExpireAllWhileServerDown +TestJetStreamStreamInfoSubjectsDetailsAfterRestart +TestJetStreamDanglingMessageAutoCleanup +``` + +**Test command:** +```bash +dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~JsStorageRecoveryTests" -v minimal +``` + +**Commit:** `test(parity): port JetStream storage, recovery & encryption tests (T6, ~26 tests) + DB update` + +--- + +### Task 7: JetStream Config, Limits & Validation (~36 tests) + +**Files:** +- Modify: `src/NATS.Server/JetStream/JetStreamService.cs` +- Modify: `src/NATS.Server/JetStream/StreamManager.cs` +- Modify: `src/NATS.Server/JetStream/Validation/JetStreamConfigValidator.cs` +- Create: `tests/NATS.Server.Tests/JetStream/JsConfigLimitsTests.cs` +- Modify: `docs/test_parity.db` + +**Feature work:** +1. Add tiered JetStream limits — per-account storage by replica factor (R1, R3). Go ref: `jetstream.go:tieredLimits` +2. Add reserved storage allocation tracking +3. Add pedantic/strict mode validation for stream creation +4. Add subject overlap detection between streams +5. Add auto-tune filesystem config based on system resources. Go ref: `jetstream.go:autoTuneFS` + +**Go tests to port (~36):** +``` +TestJetStreamAutoTuneFSConfig +TestJetStreamServerDomainConfig +TestJetStreamServerResourcesConfig +TestJetStreamSystemLimitsPlacement +TestJetStreamTieredLimits +TestJetStreamDisabledLimitsEnforcement +TestJetStreamWouldExceedLimits +TestJetStreamStorageReservedBytes +TestJetStreamUsageNoReservation +TestJetStreamUsageReservationNegativeMaxBytes +TestJetStreamGetLastMsgBySubjectAfterUpdate +TestJetStreamProperErrorDueToOverlapSubjects +TestJetStreamStreamCreatePedanticMode +TestJetStreamStrictMode +TestJetStreamBadSubjectMappingStream +TestJetStreamCreateStreamWithSubjectDeleteMarkersOptions +TestJetStreamLimitLockBug +TestJetStreamStoreFilterIsAll +TestJetStreamCleanupNoInterestAboveThreshold +TestJetStreamServerReload +TestJetStreamConfigReloadWithGlobalAccount +TestJetStreamImportReload +TestJetStreamOperatorAccounts +TestJetStreamNoPanicOnRaceBetweenShutdownAndConsumerDelete +TestJetStreamReloadMetaCompact +``` + +**Test command:** +```bash +dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~JsConfigLimitsTests" -v minimal +``` + +**Commit:** `test(parity): port JetStream config, limits & validation tests (T7, ~36 tests) + DB update` + +--- + +### Task 8: JetStream Delivery, Ack & Multi-Account (~39 tests) + +**Files:** +- Modify: `src/NATS.Server/JetStream/Consumers/PushConsumerEngine.cs` +- Modify: `src/NATS.Server/JetStream/Consumers/AckProcessor.cs` +- Modify: `src/NATS.Server/JetStream/StreamManager.cs` +- Create: `tests/NATS.Server.Tests/JetStream/JsDeliveryAckTests.cs` +- Modify: `docs/test_parity.db` + +**Feature work:** +1. Enhance NAK handling — NAK with delay, NAK of already-acked messages rejection +2. Add idle heartbeat generation for push consumers with no interest +3. Enhance interest retention with wildcards and filtered consumers +4. Add dedup window (Nats-Msg-Id header tracking). Go ref: `stream.go:checkMsgId` +5. Add cross-account JetStream access via imports/exports + +**Go tests to port (~39):** +``` +TestJetStreamRedeliverAndLateAck +TestJetStreamCanNotNakAckd +TestJetStreamNakRedeliveryWithNoWait +TestJetStreamPushConsumerIdleHeartbeatsWithNoInterest +TestJetStreamPendingNextTimer +TestJetStreamInterestRetentionWithWildcardsAndFilteredConsumers +TestJetStreamInterestRetentionStreamWithDurableRestart +TestJetStreamInterestStreamConsumerFilterEdit +TestJetStreamInterestStreamWithFilterSubjectsConsumer +TestJetStreamAckAllWithLargeFirstSequenceAndNoAckFloor +TestJetStreamDeliverLastPerSubjectNumPending +TestJetStreamDeliverLastPerSubjectWithKV +TestJetStreamWorkQueueWorkingIndicator +TestJetStreamInvalidDeliverSubject +TestJetStreamFlowControlStall +TestJetStreamFlowControlCrossAccountFanOut +TestJetStreamMsgIDHeaderCollision +TestJetStreamMultipleAccountsBasics +TestJetStreamAccountImportJSAdvisoriesAsService +TestJetStreamAccountImportJSAdvisoriesAsStream +TestJetStreamCrossAccountsDeliverSubjectInterest +TestJetStreamCrossAccountsFanOut +TestJetStreamCrossAccounts +TestJetStreamImportConsumerStreamSubjectRemapSingle +TestJetStreamSingleInstanceRemoteAccess +TestJetStreamMemoryCorruption +TestJetStreamMessagePerSubjectKeepBug +TestJetStreamRedeliveryAfterServerRestart +TestJetStreamKVDelete +TestJetStreamKVHistoryRegression +TestJetStreamKVReductionInHistory +TestJetStreamGetNoHeaders +TestJetStreamKVNoSubjectDeleteMarkerOnPurgeMarker +TestJetStreamAllowMsgCounter +``` + +**Test command:** +```bash +dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~JsDeliveryAckTests" -v minimal +``` + +**Commit:** `test(parity): port JetStream delivery, ack & multi-account tests (T8, ~39 tests) + DB update` + +--- + +### Task 9: JetStream Batching API (~29 tests) + +**Files:** +- Create: `src/NATS.Server/JetStream/Publish/BatchPublisher.cs` +- Modify: `src/NATS.Server/JetStream/Api/Handlers/StreamApiHandlers.cs` +- Modify: `src/NATS.Server/JetStream/StreamManager.cs` +- Create: `tests/NATS.Server.Tests/JetStream/JsBatchingTests.cs` +- Modify: `docs/test_parity.db` + +**Feature work:** +1. Create `BatchPublisher` — atomic multi-message publish with stage/commit/rollback semantics. Go ref: `jetstream.go:processAtomicBatch` +2. Add batch markers to storage layer (begin-of-batch, end-of-batch) +3. Add batch recovery on server restart — detect partial batches, rollback incomplete ones +4. Add batch advisory events +5. Add per-subject expected sequence validation in batches + +**Go tests to port (~29):** +``` +TestJetStreamAtomicBatchPublish +TestJetStreamAtomicBatchPublishEmptyAck +TestJetStreamAtomicBatchPublishCommitEob +TestJetStreamAtomicBatchPublishLimits +TestJetStreamAtomicBatchPublishDedupeNotAllowed +TestJetStreamAtomicBatchPublishSourceAndMirror +TestJetStreamAtomicBatchPublishCleanup +TestJetStreamAtomicBatchPublishConfigOpts +TestJetStreamAtomicBatchPublishDenyHeaders +TestJetStreamAtomicBatchPublishStageAndCommit +TestJetStreamAtomicBatchPublishHighLevelRollback +TestJetStreamAtomicBatchPublishExpectedPerSubject +TestJetStreamAtomicBatchPublishSingleServerRecovery +TestJetStreamAtomicBatchPublishSingleServerRecoveryCommitEob +TestJetStreamAtomicBatchPublishEncode +TestJetStreamAtomicBatchPublishProposeOne +TestJetStreamAtomicBatchPublishProposeMultiple +TestJetStreamAtomicBatchPublishProposeOnePartialBatch +TestJetStreamAtomicBatchPublishProposeMultiplePartialBatches +TestJetStreamAtomicBatchPublishContinuousBatchesStillMoveAppliedUp +TestJetStreamAtomicBatchPublishPartiallyAppliedBatchOnRecovery +TestJetStreamRollupIsolatedRead +TestJetStreamAtomicBatchPublishAdvisories +TestJetStreamAtomicBatchPublishExpectedSeq +TestJetStreamAtomicBatchPublishPartialBatchInSharedAppendEntry +TestJetStreamAtomicBatchPublishRejectPartialBatchOnLeaderChange +TestJetStreamAtomicBatchPublishPersistModeAsync +TestJetStreamAtomicBatchPublishExpectedLastSubjectSequence +TestJetStreamAtomicBatchPublishCommitUnsupported +``` + +**Test command:** +```bash +dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~JsBatchingTests" -v minimal +``` + +**Commit:** `test(parity): port JetStream atomic batch publish API (T9, 29 tests) + DB update` + +--- + +### Task 10: JetStream Versioning & Direct Get (~48 tests) + +**Files:** +- Modify: `src/NATS.Server/JetStream/Models/StreamConfig.cs` (or equivalent) +- Modify: `src/NATS.Server/JetStream/Api/Handlers/DirectApiHandlers.cs` +- Create: `tests/NATS.Server.Tests/JetStream/JsVersioningTests.cs` +- Modify: `docs/test_parity.db` + +**Feature work:** +1. Add `RequiredApiLevel` field to StreamConfig and ConsumerConfig +2. Add static/dynamic metadata fields — static immutable after creation +3. Add API version negotiation on responses +4. Add batched direct get — multi-message response with MaxBytes paging. Go ref: `jetstream_api.go:directGet` +5. Add snapshot/restore API stubs with healthz integration + +**Go tests to port (~48):** +All 18 from jetstream_versioning_test.go plus remaining jetstream_test.go tests: +``` +TestGetAndSupportsRequiredApiLevel +TestJetStreamSetStaticStreamMetadata +TestJetStreamSetStaticStreamMetadataRemoveDynamicFields +TestJetStreamSetDynamicStreamMetadata +TestJetStreamCopyStreamMetadata +TestJetStreamCopyStreamMetadataRemoveDynamicFields +TestJetStreamSetStaticConsumerMetadata +TestJetStreamSetStaticConsumerMetadataRemoveDynamicFields +TestJetStreamSetDynamicConsumerMetadata +TestJetStreamSetDynamicConsumerInfoMetadata +TestJetStreamCopyConsumerMetadata +TestJetStreamCopyConsumerMetadataRemoveDynamicFields +TestJetStreamMetadataMutations +TestJetStreamMetadataStreamRestoreAndRestart +TestJetStreamMetadataStreamRestoreAndRestartCluster +TestJetStreamApiErrorOnRequiredApiLevel +TestJetStreamApiErrorOnRequiredApiLevelDirectGet +TestJetStreamApiErrorOnRequiredApiLevelPullConsumerNextMsg +TestJetStreamDirectGetBatchMaxBytes +TestJetStreamDirectGetMultiUpToTime +TestJetStreamDirectGetMultiMaxAllowed +TestJetStreamDirectGetMultiPaging +TestJetStreamDirectGetSubjectDeleteMarker +TestJetStreamDirectGetBatchParallelWriteDeadlock +TestJetStreamSnapshotRestoreStallAndHealthz +TestJetStreamUpgradeStreamVersioning +TestJetStreamUpgradeConsumerVersioning +TestJetStreamOfflineStreamAndConsumerAfterDowngrade +``` + +**Test command:** +```bash +dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~JsVersioningTests" -v minimal +``` + +**Commit:** `test(parity): port JetStream versioning, metadata & direct get tests (T10, ~48 tests) + DB update` + +--- + +## Track 3: JetStream Cluster (296 tests) + +> **Dependency:** Track 1 (Tasks 1-4) should complete first for storage reliability. + +### Task 11: JetStream Cluster Batch 1 — Meta Recovery & Consumer State (~73 tests) + +**Files:** +- Modify: `src/NATS.Server/JetStream/Cluster/JetStreamMetaGroup.cs` +- Modify: `tests/NATS.Server.Tests/JetStream/Cluster/JetStreamClusterFixture.cs` +- Create: `tests/NATS.Server.Tests/JetStream/Cluster/JsCluster1GoParityTests.cs` +- Modify: `docs/test_parity.db` + +**Feature work:** +1. Enhance `JetStreamClusterFixture` — add multi-node simulation (3-node), add partition simulation +2. Add inflight request dedup in MetaGroup +3. Add meta recovery for consumer creates/deletes. Go ref: `jetstream_cluster.go:processStreamAssignment` +4. Add health check simulation — stream and consumer health status reporting + +**Go tests to port:** All 73 unmapped from `jetstream_cluster_1_test.go` (see exploration output above). + +**Test command:** +```bash +dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~JsCluster1GoParityTests" -v minimal +``` + +**Commit:** `test(parity): port JetStream cluster-1 tests (T11, 73 tests) + DB update` + +--- + +### Task 12: JetStream Cluster Batch 2 — Cross-Domain & Rollups (~92 tests) + +**Files:** +- Modify: `tests/NATS.Server.Tests/JetStream/Cluster/JetStreamClusterFixture.cs` +- Create: `tests/NATS.Server.Tests/JetStream/Cluster/JsCluster2GoParityTests.cs` +- Modify: `docs/test_parity.db` + +**Feature work:** +1. Add domain simulation in cluster fixture — cross-domain source/mirror +2. Add mixed-mode cluster simulation (some nodes with JS, some without) +3. Add rollup support (KV-style subject rollup semantics) +4. Add consumer NAK/backoff in cluster context + +**Go tests to port:** All 92 unmapped from `jetstream_cluster_2_test.go` (see exploration output above). + +**Test command:** +```bash +dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~JsCluster2GoParityTests" -v minimal +``` + +**Commit:** `test(parity): port JetStream cluster-2 tests (T12, 92 tests) + DB update` + +--- + +### Task 13: JetStream Cluster Batch 3 — Scale, Move & Pause (~131 tests) + +**Files:** +- Modify: `src/NATS.Server/JetStream/Cluster/JetStreamMetaGroup.cs` +- Modify: `src/NATS.Server/JetStream/Cluster/StreamReplicaGroup.cs` +- Create: `tests/NATS.Server.Tests/JetStream/Cluster/JsCluster34GoParityTests.cs` +- Modify: `docs/test_parity.db` + +**Feature work:** +1. Add stream/consumer scale up/down simulation — change replica count dynamically +2. Add stream move simulation — relocate stream to different nodes +3. Add consumer pause in cluster context with leader handoff +4. Add lame duck mode simulation +5. Add orphan NRG detection and cleanup + +**Go tests to port:** All 64 from `jetstream_cluster_3_test.go` + all 61 from `jetstream_cluster_4_test.go` + 6 from `jetstream_cluster_long_test.go` (see exploration output). + +**Test command:** +```bash +dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~JsCluster34GoParityTests" -v minimal +``` + +**Commit:** `test(parity): port JetStream cluster-3/4/long tests (T13, ~131 tests) + DB update` + +--- + +## Track 4: Consumer Engines (96 tests) + +### Task 14: Consumer Pull Queue, State & Filters (~48 tests) + +**Gaps addressed:** Gap 4 — HIGH + +**Files:** +- Modify: `src/NATS.Server/JetStream/Consumers/PullConsumerEngine.cs` +- Modify: `src/NATS.Server/JetStream/Consumers/AckProcessor.cs` +- Modify: `src/NATS.Server/JetStream/ConsumerManager.cs` +- Create: `tests/NATS.Server.Tests/JetStream/Consumers/ConsumerPullQueueTests.cs` +- Modify: `docs/test_parity.db` + +**Feature work:** +1. Add pull request queue with priority ordering. Go ref: `consumer.go:waitingPending` +2. Add MaxWaiting enforcement — limit concurrent pull requests per consumer +3. Add pull request cleanup/expiry — remove stale requests +4. Add multi-filter race condition handling — safe concurrent filter evaluation +5. Add batch completion detection — track when all requested messages delivered +6. Add MaxBytes enforcement on pull responses +7. Add NoWait behavior for empty pending + +**Go tests to port (~48):** +``` +TestJetStreamConsumerPullMaxAckPending +TestJetStreamConsumerPullConsumerFIFO +TestJetStreamConsumerPullConsumerOneShotOnMaxAckLimit +TestJetStreamConsumerPullMaxWaitingOfOne +TestJetStreamConsumerPullMaxWaiting +TestJetStreamConsumerPullRequestCleanup +TestJetStreamConsumerPullRequestMaximums +TestJetStreamConsumerPullCrossAccountExpires +TestJetStreamConsumerPullCrossAccountExpiresNoDataRace +TestJetStreamConsumerPullCrossAccountsAndLeafNodes +TestJetStreamConsumerPullOneShotBehavior +TestJetStreamConsumerPullMultipleRequestsExpireOutOfOrder +TestJetStreamConsumerPullLastPerSubjectRedeliveries +TestJetStreamConsumerPullTimeoutHeaders +TestJetStreamConsumerPullBatchCompleted +TestJetStreamConsumerPullLargeBatchExpired +TestJetStreamConsumerPullTimeout +TestJetStreamConsumerPullMaxBytes +TestJetStreamConsumerPullNoWaitBatchLargerThanPending +TestJetStreamConsumerPullRemoveInterest +TestJetStreamConsumerPullDelayedFirstPullWithReplayOriginal +TestJetStreamConsumerMultipleFiltersRace +TestJetStreamConsumerMultipleFitersWithStartDate +TestJetStreamConsumerMultipleSubjectsLast +TestJetStreamConsumerMultipleSubjectsLastPerSubject +TestJetStreamConsumerMultipleSubjectsWithEmpty +TestJetStreamConsumerMultipleSubjectsAck +TestJetStreamConsumerMultipleSubjectAndNewAPI +TestJetStreamConsumerMultipleSubjectsWithAddedMessages +TestJetStreamConsumerThreeFilters +TestJetStreamConsumerUpdateFilterSubjects +TestJetStreamConsumerFilterUpdate +TestJetStreamConsumerIsFiltered +TestJetStreamConsumerSingleFilterSubjectInFilterSubjects +TestSortingConsumerPullRequests +TestWaitQueuePopAndRequeue +TestJetStreamConsumerStateAlwaysFromStore +TestJetStreamConsumerCheckNumPending +TestJetStreamConsumerOnlyRecalculatePendingIfFilterSubjectUpdated +TestJetStreamConsumerAllowOverlappingSubjectsIfNotSubset +TestJetStreamConsumerBadNumPending +TestJetStreamConsumerPendingCountWithRedeliveries +TestJetStreamConsumerPendingCountAfterMsgAckAboveFloor +TestJetStreamConsumerDontDecrementPendingCountOnSkippedMsg +TestJetStreamConsumerNumPendingWithMaxPerSubjectGreaterThanOne +TestJetStreamConsumerPendingLowerThanStreamFirstSeq +TestJetStreamConsumerInfoNumPending +TestJetStreamConsumerEfficientInterestStateCheck +``` + +**Test command:** +```bash +dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~ConsumerPullQueueTests" -v minimal +``` + +**Commit:** `test(parity): port consumer pull queue, state & filter tests (T14, ~48 tests) + DB update` + +--- + +### Task 15: Consumer Pause, Replay, Priority & Lifecycle (~48 tests) + +**Files:** +- Modify: `src/NATS.Server/JetStream/Consumers/PushConsumerEngine.cs` +- Modify: `src/NATS.Server/JetStream/Consumers/PriorityGroupManager.cs` +- Modify: `src/NATS.Server/JetStream/Consumers/RedeliveryTracker.cs` +- Modify: `src/NATS.Server/JetStream/ConsumerManager.cs` +- Create: `tests/NATS.Server.Tests/JetStream/Consumers/ConsumerLifecycleTests.cs` +- Modify: `docs/test_parity.db` + +**Feature work:** +1. Add consumer pause/resume — state machine with Pause(until), Resume(), advisory publication +2. Add replay rate matching — deliver at original publish timestamps. Go ref: `consumer.go:replayRate` +3. Add priority pull requests — priority-based consumer ordering. Go ref: `consumer.go:prioritized` +4. Add consumer state persistence — survive server restart. Go ref: `consumer.go:writeState` +5. Add max delivery underflow handling +6. Add inactive threshold for ephemeral consumer cleanup + +**Go tests to port (~48):** +``` +TestJetStreamConsumerPauseViaConfig +TestJetStreamConsumerPauseViaEndpoint +TestJetStreamConsumerPauseResumeViaEndpoint +TestJetStreamConsumerPauseAdvisories +TestJetStreamConsumerReplayRate +TestJetStreamConsumerReplayQuit +TestJetStreamConsumerPrioritized +TestJetStreamConsumerPriorityPullRequests +TestJetStreamConsumerMaxDeliverUnderflow +TestJetStreamConsumerNoWaitNoMessagesOnEos +TestJetStreamConsumerNoWaitNoMessagesOnEosWithDeliveredMsgs +TestJetStreamConsumerActionsViaAPI +TestJetStreamConsumerActionsUnmarshal +TestJetStreamConsumerWorkQueuePolicyOverlap +TestJetStreamConsumerLongSubjectHang +TestJetStreamConsumerStuckAckPending +TestJetStreamConsumerSwitchLeaderDuringInflightAck +TestJetStreamConsumerEphemeralRecoveryAfterServerRestart +TestJetStreamConsumerMaxDeliveryAndServerRestart +TestJetStreamConsumerDeleteAndServerRestart +TestJetStreamConsumerDurableReconnectWithOnlyPending +TestJetStreamConsumerDurableFilteredSubjectReconnect +TestJetStreamConsumerInactiveNoDeadlock +TestJetStreamConsumerReconnect +TestJetStreamConsumerDeliverNewMaxRedeliveriesAndServerRestart +TestJetStreamConsumerEOFBugNewFileStore +TestJetStreamConsumerCleanupWithRetentionPolicy +TestJetStreamConsumerPendingBugWithKV +TestJetStreamConsumerBadCreateErr +TestJetStreamConsumerInternalClientLeak +TestJetStreamConsumerEventingRaceOnShutdown +TestJetStreamConsumerNoMsgPayload +TestJetStreamConsumerUpdateSurvival +TestJetStreamConsumerAckSamplingSpecifiedUsingUpdateConsumer +TestJetStreamConsumerStreamUpdate +TestJetStreamConsumerAndStreamNamesWithPathSeparators +TestJetStreamConsumerUpdateFilterSubject +TestJetStreamConsumerAndStreamMetadata +TestJetStreamConsumerDefaultsFromStream +TestJetStreamConsumerWithFormattingSymbol +TestJetStreamConsumerWithCorruptStateIsDeleted +TestJetStreamConsumerNoDeleteAfterConcurrentShutdownAndLeaderChange +TestJetStreamConsumerResetToSequenceConstraintOnStartSeq +TestJetStreamConsumerResetToSequenceConstraintOnStartTime +TestJetStreamConsumerLegacyDurableCreateSetsConsumerName +TestJetStreamConsumerNotInactiveDuringAckWait +``` + +**Test command:** +```bash +dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~ConsumerLifecycleTests" -v minimal +``` + +**Commit:** `test(parity): port consumer pause, replay, priority & lifecycle tests (T15, ~48 tests) + DB update` + +--- + +## Track 5: Auth/JWT/Accounts (105 tests) + +### Task 16: JWT Claims & Account Resolver (~61 tests) + +**Gaps addressed:** Gap 9 — MEDIUM + +**Files:** +- Modify: `src/NATS.Server/Auth/JwtAuthenticator.cs` +- Modify: `src/NATS.Server/Auth/AccountClaims.cs` +- Modify: `src/NATS.Server/Auth/AccountResolver.cs` +- Create: `tests/NATS.Server.Tests/Auth/JwtGoParityTests.cs` +- Modify: `docs/test_parity.db` + +**Feature work:** +1. Add full operator→account→user trust chain validation. Go ref: `jwt.go:validateTrustedOperators` +2. Add signing key hierarchy — operator signing keys, account signing keys +3. Add account URL resolver with fetch, timeout, retry. Go ref: `accounts.go:URLAccResolver` +4. Add NATS resolver — resolve accounts via NATS request/reply. Go ref: `accounts.go:NATSAccResolver` +5. Add JWT expiration handling — disconnect expired users/accounts +6. Add import activation — activation tokens with expiration +7. Add account limits from JWT claims — max connections, payload, subs + +**Go tests to port:** All 61 from jwt_test.go (see exploration output above). + +**Test command:** +```bash +dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~JwtGoParityTests" -v minimal +``` + +**Commit:** `test(parity): port JWT claims & account resolver tests (T16, 61 tests) + DB update` + +--- + +### Task 17: Auth Callout (~30 tests) + +**Files:** +- Create: `src/NATS.Server/Auth/AuthCalloutHandler.cs` +- Modify: `src/NATS.Server/Auth/AuthService.cs` +- Create: `tests/NATS.Server.Tests/Auth/AuthCalloutGoParityTests.cs` +- Modify: `docs/test_parity.db` + +**Feature work:** +1. Create `AuthCalloutHandler` — external auth delegation via NATS request/reply. Go ref: `auth_callout.go` +2. Add callout with TLS client certificate forwarding +3. Add callout with operator mode and encryption +4. Add callout error response handling +5. Add callout with leaf node integration + +**Go tests to port:** All 30 from auth_callout_test.go (see exploration output above). + +**Test command:** +```bash +dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~AuthCalloutGoParityTests" -v minimal +``` + +**Commit:** `test(parity): port auth callout tests (T17, 30 tests) + DB update` + +--- + +### Task 18: Account Imports/Exports & Routing (~14 tests) + +**Files:** +- Modify: `src/NATS.Server/Auth/Account.cs` +- Modify: `src/NATS.Server/Auth/AuthService.cs` +- Create: `tests/NATS.Server.Tests/Auth/AccountRoutingTests.cs` +- Modify: `docs/test_parity.db` + +**Feature work:** +1. Add weighted subject route mappings. Go ref: `accounts.go:addMapping` +2. Add origin cluster filtering on route mappings +3. Add service/stream export with authorization checks +4. Add system account permissions with global access +5. Add per-account system event permissions + +**Go tests to port:** All 14 from accounts_test.go (see exploration output above). + +**Test command:** +```bash +dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~AccountRoutingTests" -v minimal +``` + +**Commit:** `test(parity): port account routing & import/export tests (T18, 14 tests) + DB update` + +--- + +## Track 6: Networking (187 tests) + +### Task 19: Gateway Tests (~48 tests) + +**Gaps addressed:** Gap 11 — MEDIUM + +**Files:** +- Modify: `src/NATS.Server/Gateway/GatewayManager.cs` +- Modify: `src/NATS.Server/Gateway/GatewayConnection.cs` +- Create: `tests/NATS.Server.Tests/Gateway/GatewayGoParityTests.cs` +- Modify: `docs/test_parity.db` + +**Feature work:** +1. Add gateway auto-discovery — learn gateways from cluster gossip. Go ref: `gateway.go:solicitGateway` +2. Add gateway TLS with mutual auth and cert reload +3. Add gateway queue sub propagation. Go ref: `gateway.go:sendQSubs` +4. Add gateway interest-only mode optimization. Go ref: `gateway.go:switchToInterestOnly` +5. Add gateway service import/export with queue groups +6. Add gateway connection events (advisory publication) + +**Go tests to port:** All 48 from gateway_test.go (see exploration output above). + +**Test command:** +```bash +dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~GatewayGoParityTests" -v minimal +``` + +**Commit:** `test(parity): port gateway tests (T19, 48 tests) + DB update` + +--- + +### Task 20: Leaf Node Tests (~75 tests) + +**Gaps addressed:** Gap 12 — MEDIUM + +**Files:** +- Modify: `src/NATS.Server/LeafNode/LeafNodeManager.cs` +- Modify: `src/NATS.Server/LeafNode/LeafConnection.cs` +- Create: `tests/NATS.Server.Tests/LeafNode/LeafNodeGoParityTests.cs` +- Modify: `docs/test_parity.db` + +**Feature work:** +1. Add solicited leaf connections with TLS, retry, backoff. Go ref: `leafnode.go:solicitLeafNode` +2. Add leaf node compression negotiation (S2). Go ref: `leafnode.go:compressionNegotiation` +3. Add leaf node WebSocket support. Go ref: `leafnode.go:wsLeaf` +4. Add leaf node queue group distribution across hubs. Go ref: `leafnode.go:processLeafSub` +5. Add leaf node TLS handshake-first mode +6. Add leaf JetStream domain forwarding + +**Go tests to port:** All 55 from leafnode_test.go + 8 from leafnode_proxy_test.go + 12 from jetstream_leafnode_test.go. + +**Test command:** +```bash +dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~LeafNodeGoParityTests" -v minimal +``` + +**Commit:** `test(parity): port leaf node tests (T20, ~75 tests) + DB update` + +--- + +### Task 21: Routes & Super-Cluster (~84 tests) + +**Gaps addressed:** Gap 13 — MEDIUM + +**Files:** +- Modify: `src/NATS.Server/Route/RouteManager.cs` +- Modify: `src/NATS.Server/Route/RouteConnection.cs` +- Create: `tests/NATS.Server.Tests/Route/RouteGoParityTests.cs` +- Create: `tests/NATS.Server.Tests/JetStream/Cluster/JsSuperClusterTests.cs` +- Modify: `docs/test_parity.db` + +**Feature work:** +1. Add route pooling — multiple connections per peer. Go ref: `route.go:routePool` +2. Add route compression with S2. Go ref: `route.go:compressionNegotiation` +3. Add per-account dedicated routes. Go ref: `route.go:perAccountRoutes` +4. Add route slow consumer detection and recovery +5. Add super-cluster simulation fixture — multi-cluster topology via gateway +6. Add route TLS with implicit cert allow/reject + +**Go tests to port:** All 37 from routes_test.go + all 47 from jetstream_super_cluster_test.go. + +**Test command:** +```bash +dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~RouteGoParityTests OR FullyQualifiedName~JsSuperClusterTests" -v minimal +``` + +**Commit:** `test(parity): port route + super-cluster tests (T21, ~84 tests) + DB update` + +--- + +## Track 7: Config/Reload/Monitoring (132 tests) + +### Task 22: Configuration & Options (~49 tests) + +**Gaps addressed:** Gap 14 — MEDIUM + +**Files:** +- Modify: `src/NATS.Server/Configuration/ConfigProcessor.cs` +- Modify: `src/NATS.Server/Configuration/NatsConfParser.cs` +- Create: `tests/NATS.Server.Tests/Configuration/OptsGoParityTests.cs` +- Modify: `docs/test_parity.db` + +**Feature work:** +1. Add gateway config parsing. Go ref: `opts.go:parseGateways` +2. Add leaf node remote config parsing. Go ref: `opts.go:parseLeafNodes` +3. Add operator JWT config reading. Go ref: `opts.go:readOperatorJWT` +4. Add NKey user config parsing with permissions. Go ref: `opts.go:parseNKeys` +5. Add environment variable include/reference support. Go ref: `opts.go:envInclude` +6. Add service latency config parsing +7. Add authorization timeout config for leaf nodes + +**Go tests to port:** All 49 from opts_test.go (see exploration output above). + +**Test command:** +```bash +dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~OptsGoParityTests" -v minimal +``` + +**Commit:** `test(parity): port config & options tests (T22, 49 tests) + DB update` + +--- + +### Task 23: Config Reload (~38 tests) + +**Files:** +- Modify: `src/NATS.Server/Configuration/ConfigReloader.cs` +- Create: `tests/NATS.Server.Tests/Configuration/ReloadGoParityTests.cs` +- Modify: `docs/test_parity.db` + +**Feature work:** +1. Add TLS cert rotation on reload. Go ref: `reload.go:reloadTLS` +2. Add cluster authorization reload. Go ref: `reload.go:reloadClusterAuthorization` +3. Add cluster routes reload — add/remove solicited routes. Go ref: `reload.go:reloadClusterRoutes` +4. Add account NKey user reload +5. Add account stream/service import/export reload +6. Add route pool and per-account reload +7. Add route/leaf compression reload + +**Go tests to port:** All 38 from reload_test.go (see exploration output above). + +**Test command:** +```bash +dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~ReloadGoParityTests" -v minimal +``` + +**Commit:** `test(parity): port config reload tests (T23, 38 tests) + DB update` + +--- + +### Task 24: Monitoring Endpoints (~45 tests) + +**Gaps addressed:** Gap 10 — MEDIUM + +**Files:** +- Modify: `src/NATS.Server/Monitoring/ConnzHandler.cs` +- Modify: `src/NATS.Server/Monitoring/Varz.cs` +- Create: `tests/NATS.Server.Tests/Monitoring/MonitorGoParityTests.cs` +- Modify: `docs/test_parity.db` + +**Feature work:** +1. Add connz sort by uptime, stop time for closed connections. Go ref: `monitor.go:connzSort` +2. Add connz closed connections ring buffer. Go ref: `monitor.go:closedClients` +3. Add connz TLS info reporting (handshake state, cipher suite) +4. Add operator mode account reporting in connz/accountz +5. Add gateway URL reporting in gatewayz. Go ref: `monitor.go:gatewayz` +6. Add leafz endpoint with full leaf connection details +7. Add healthz with JetStream availability check +8. Add varz metadata, sync interval, TLS cert expiry +9. Add profilez endpoint + +**Go tests to port:** All 45 from monitor_test.go (see exploration output above). + +**Test command:** +```bash +dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~MonitorGoParityTests" -v minimal +``` + +**Commit:** `test(parity): port monitoring endpoint tests (T24, 45 tests) + DB update` + +--- + +## Track 8: Client/Protocol/Misc (112 tests) + +### Task 25: Client Protocol & Server Lifecycle (~50 tests) + +**Gaps addressed:** Gap 5 — HIGH + +**Files:** +- Modify: `src/NATS.Server/NatsClient.cs` +- Modify: `src/NATS.Server/NatsServer.cs` +- Create: `tests/NATS.Server.Tests/ClientServerGoParityTests.cs` +- Modify: `docs/test_parity.db` + +**Feature work:** +1. Add TLS handshake-first mode — TLS before INFO. Go ref: `client.go:tlsHandshakeFirst` +2. Add write timeout policy configuration. Go ref: `client.go:writeTimeout` +3. Add slow consumer write loop stall detection +4. Add server rate limit logging +5. Add in-process connection type support +6. Add semantic version parsing. Go ref: `server.go:versionComponents` +7. Add profiler and monitoring port startup + +**Go tests to port:** All 22 from client_test.go + all 28 from server_test.go. + +**Test command:** +```bash +dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~ClientServerGoParityTests" -v minimal +``` + +**Commit:** `test(parity): port client protocol & server lifecycle tests (T25, ~50 tests) + DB update` + +--- + +### Task 26: PROXY Protocol & SubList (~48 tests) + +**Files:** +- Create: `src/NATS.Server/Protocol/ProxyProtocol.cs` +- Modify: `src/NATS.Server/Subscriptions/SubList.cs` +- Create: `tests/NATS.Server.Tests/Protocol/ProxyProtocolTests.cs` +- Create: `tests/NATS.Server.Tests/Subscriptions/SubListGoParityTests.cs` +- Modify: `docs/test_parity.db` + +**Feature work:** +1. Create PROXY protocol v1/v2 parser — extract source IP/port from load balancer header. Go ref: `client.go:parseProxyProto` +2. Add v1 (text-based TCP4/TCP6/UNKNOWN) and v2 (binary IPv4/IPv6/LOCAL) support +3. Add SubList interest notification registration. Go ref: `sublist.go:RegisterNotification` +4. Add SubList subject collision detection +5. Add SubList cache hit rate tracking + +**Go tests to port:** All 23 from client_proxyproto_test.go + all 25 from sublist_test.go. + +**Test command:** +```bash +dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~ProxyProtocolTests OR FullyQualifiedName~SubListGoParityTests" -v minimal +``` + +**Commit:** `test(parity): port PROXY protocol + SubList tests (T26, ~48 tests) + DB update` + +--- + +### Task 27: Message Trace, Closed Conns & Infrastructure (~70 tests) + +**Files:** +- Modify: `src/NATS.Server/Internal/MessageTraceContext.cs` +- Create: `tests/NATS.Server.Tests/MsgTraceGoParityTests.cs` +- Create: `tests/NATS.Server.Tests/InfrastructureGoParityTests.cs` +- Modify: `docs/test_parity.db` + +**Feature work:** +1. Add message trace propagation through routes, leaf nodes, gateways. Go ref: `msgtrace.go` +2. Add trace with compression support +3. Add trace triggered by external header +4. Add trace with JetStream and super-cluster +5. Add closed connection tracking with reason codes. Go ref: `client.go:closedConns` +6. Port remaining infrastructure tests: parser, log, errors, config_check, auth, jetstream_errors, jetstream_jwt, jetstream_tpm, trust, subject_transform, nkey, ping, rate_counter, util, mqtt_ex + +**Go tests to port:** All 22 from msgtrace_test.go + 6 from closed_conns_test.go + remaining infrastructure tests (~42): +``` +# parser_test.go (5) +TestServerInfoNonceAlwaysEnabled, TestParseRoutedHeaderMsg, TestParseRouteMsg, TestParseMsgSpace, TestProtoSnippet + +# log_test.go (4) +TestSetLogger, TestReOpenLogFile, TestRemovePassFromTrace, TestRemoveAuthTokenFromTrace + +# errors_test.go (2) +TestErrCtx, TestErrCtxWrapped + +# config_check_test.go (2) +TestConfigCheck, TestConfigCheckMultipleErrors + +# auth_test.go (2) +TestDNSAltNameMatching, TestNoAuthUserNoConnectProto + +# jetstream_errors_test.go (4) +TestIsNatsErr, TestApiError_Error, TestApiError_NewWithTags, TestApiError_NewWithUnless + +# jetstream_jwt_test.go (18) +TestJetStreamJWTLimits, TestJetStreamJWTDisallowBearer, TestJetStreamJWTMove, TestJetStreamJWTClusteredTiers, ... + +# jetstream_tpm_test.go (5) +TestJetStreamTPMBasic, TestJetStreamTPMKeyBadPassword, TestJetStreamTPMKeyWithPCR, TestJetStreamTPMAll, ... + +# trust_test.go (3) +TestStampedTrustedKeys, TestTrustedKeysOptions, TestTrustConfigOption + +# subject_transform_test.go (3) +TestSubjectTransforms, TestSubjectTransformDoesntPanicTransformingMissingToken, ... + +# nkey_test.go (1), ping_test.go (1), rate_counter_test.go (1) +# util_test.go (6), mqtt_ex_test_test.go (2) +``` + +**Test command:** +```bash +dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~MsgTraceGoParityTests OR FullyQualifiedName~InfrastructureGoParityTests" -v minimal +``` + +**Commit:** `test(parity): port message trace + infrastructure tests (T27, ~70 tests) + DB update` + +--- + +## Task 28: Full Test Suite Verification & DB Reconciliation + +**Step 1: Run full test suite** + +```bash +dotnet test tests/NATS.Server.Tests -v minimal +``` + +Expected: 6,000+ tests passing, 0 failures. + +**Step 2: Verify DB status** + +```bash +sqlite3 docs/test_parity.db "SELECT status, COUNT(*) FROM go_tests GROUP BY status" +``` + +Expected: +- mapped: ~2,666 (90.8%) +- not_applicable: ~268 +- skipped: 3 +- unmapped: ~0 + +**Step 3: Generate summary report** + +```bash +sqlite3 docs/test_parity.db "SELECT go_file, COUNT(*) as total, SUM(status='mapped') as mapped, SUM(status='unmapped') as unmapped, SUM(status='not_applicable') as na FROM go_tests GROUP BY go_file ORDER BY unmapped DESC" +``` + +**Step 4: Commit final state** + +```bash +git add docs/test_parity.db +git commit -m "chore: final parity DB reconciliation — target 90%+ mapped" +``` + +--- + +## Execution Summary + +| Task | Track | Tests | Dependencies | +|------|-------|------:|-------------| +| T0 | — | ~222 (mark n/a) | None | +| T1 | 1: Storage | ~50 | None | +| T2 | 1: Storage | ~40 | None | +| T3 | 1: Storage | ~28 | None | +| T4 | 1: Storage | ~16 | T1-T3 | +| T5 | 2: JS Core | ~42 | None | +| T6 | 2: JS Core | ~26 | None | +| T7 | 2: JS Core | ~36 | None | +| T8 | 2: JS Core | ~39 | None | +| T9 | 2: JS Core | ~29 | None | +| T10 | 2: JS Core | ~48 | None | +| T11 | 3: JS Cluster | ~73 | T1-T4 | +| T12 | 3: JS Cluster | ~92 | T1-T4 | +| T13 | 3: JS Cluster | ~131 | T1-T4 | +| T14 | 4: Consumer | ~48 | None | +| T15 | 4: Consumer | ~48 | None | +| T16 | 5: Auth/JWT | ~61 | None | +| T17 | 5: Auth/JWT | ~30 | None | +| T18 | 5: Auth/JWT | ~14 | None | +| T19 | 6: Network | ~48 | None | +| T20 | 6: Network | ~75 | None | +| T21 | 6: Network | ~84 | None | +| T22 | 7: Config | ~49 | None | +| T23 | 7: Config | ~38 | None | +| T24 | 7: Monitor | ~45 | None | +| T25 | 8: Client | ~50 | None | +| T26 | 8: Protocol | ~48 | None | +| T27 | 8: Misc | ~70 | None | +| T28 | — | Verify | All | +| **Total** | | **~1,418** | | + +### Parallelism + +**Independent (can run in parallel):** T0, T1-T3, T5-T10, T14-T15, T16-T18, T19-T21, T22-T24, T25-T27 + +**Sequential within track:** +- Track 1: T1→T2→T3→T4 +- Track 3: Waits for Track 1 completion, then T11→T12→T13 + +**Final:** T28 runs after all others complete. diff --git a/docs/plans/2026-02-24-remaining-parity-plan.md.tasks.json b/docs/plans/2026-02-24-remaining-parity-plan.md.tasks.json new file mode 100644 index 0000000..9f7fcbe --- /dev/null +++ b/docs/plans/2026-02-24-remaining-parity-plan.md.tasks.json @@ -0,0 +1,35 @@ +{ + "planPath": "docs/plans/2026-02-24-remaining-parity-plan.md", + "tasks": [ + {"id": 0, "subject": "Task 0: Mark ~224 not-applicable tests in DB", "status": "pending"}, + {"id": 1, "subject": "Task 1: FileStore block recovery & compaction (~50 tests)", "status": "pending"}, + {"id": 2, "subject": "Task 2: FileStore tombstones, deletion & TTL (~40 tests)", "status": "pending"}, + {"id": 3, "subject": "Task 3: MemStore Go-parity methods (~28 tests)", "status": "pending"}, + {"id": 4, "subject": "Task 4: Store interface contract tests (~16 tests)", "status": "pending", "blockedBy": [1, 2, 3]}, + {"id": 5, "subject": "Task 5: JetStream mirrors, sources & transforms (~42 tests)", "status": "pending"}, + {"id": 6, "subject": "Task 6: JetStream storage, recovery & encryption (~26 tests)", "status": "pending"}, + {"id": 7, "subject": "Task 7: JetStream config, limits & validation (~36 tests)", "status": "pending"}, + {"id": 8, "subject": "Task 8: JetStream delivery, ack & multi-account (~39 tests)", "status": "pending"}, + {"id": 9, "subject": "Task 9: JetStream atomic batch publish API (~29 tests)", "status": "pending"}, + {"id": 10, "subject": "Task 10: JetStream versioning, metadata & direct get (~48 tests)", "status": "pending"}, + {"id": 11, "subject": "Task 11: JetStream cluster batch 1 — meta recovery (~73 tests)", "status": "pending", "blockedBy": [1, 2, 3, 4]}, + {"id": 12, "subject": "Task 12: JetStream cluster batch 2 — cross-domain (~92 tests)", "status": "pending", "blockedBy": [1, 2, 3, 4]}, + {"id": 13, "subject": "Task 13: JetStream cluster batch 3 — scale/move/pause (~131 tests)", "status": "pending", "blockedBy": [1, 2, 3, 4]}, + {"id": 14, "subject": "Task 14: Consumer pull queue, state & filters (~48 tests)", "status": "pending"}, + {"id": 15, "subject": "Task 15: Consumer pause, replay, priority & lifecycle (~48 tests)", "status": "pending"}, + {"id": 16, "subject": "Task 16: JWT claims & account resolver (~61 tests)", "status": "pending"}, + {"id": 17, "subject": "Task 17: Auth callout (~30 tests)", "status": "pending"}, + {"id": 18, "subject": "Task 18: Account imports/exports & routing (~14 tests)", "status": "pending"}, + {"id": 19, "subject": "Task 19: Gateway tests (~48 tests)", "status": "pending"}, + {"id": 20, "subject": "Task 20: Leaf node tests (~75 tests)", "status": "pending"}, + {"id": 21, "subject": "Task 21: Routes & super-cluster tests (~84 tests)", "status": "pending"}, + {"id": 22, "subject": "Task 22: Configuration & options tests (~49 tests)", "status": "pending"}, + {"id": 23, "subject": "Task 23: Config reload tests (~38 tests)", "status": "pending"}, + {"id": 24, "subject": "Task 24: Monitoring endpoint tests (~45 tests)", "status": "pending"}, + {"id": 25, "subject": "Task 25: Client protocol & server lifecycle (~50 tests)", "status": "pending"}, + {"id": 26, "subject": "Task 26: PROXY protocol & SubList tests (~48 tests)", "status": "pending"}, + {"id": 27, "subject": "Task 27: Message trace + infrastructure tests (~70 tests)", "status": "pending"}, + {"id": 28, "subject": "Task 28: Full test suite verification & DB reconciliation", "status": "pending", "blockedBy": [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27]} + ], + "lastUpdated": "2026-02-24T12:00:00Z" +}