27 KiB
NATS Strict Full Go Parity Implementation Plan
For Codex: REQUIRED SUB-SKILL: Use
executeplanto implement this plan task-by-task.
Goal: Port all remaining NATS functionality gaps from Go to .NET at capability level (not table-status level), with behavior-complete implementation, unit/integration coverage, and synchronized parity documentation.
Architecture: Execute in dependency layers: inter-server fabric first, then MQTT wire/runtime parity, then JetStream runtime state machines, then storage/RAFT/cluster governance, then operational parity and docs synchronization. Every capability closes only when Behavior + Tests + Docs are complete.
Tech Stack: .NET 10, C# 14, xUnit 3, Shouldly, System.IO.Pipelines, ASP.NET Core monitoring endpoints, custom protocol parsers, integration socket fixtures.
Execution guardrails
- Use
@test-driven-developmentfor each task. - If expected contracts and observed runtime behavior diverge, switch to
@systematic-debuggingbefore changing production code. - Keep one commit per task.
- Run
@verification-before-completionbefore final parity status updates.
Task 1: Add Strict Capability Inventory Guardrail
Files:
- Create:
docs/plans/2026-02-23-nats-strict-full-go-parity-map.md - Create:
tests/NATS.Server.Tests/Parity/NatsStrictCapabilityInventoryTests.cs - Create:
tests/NATS.Server.Tests/Parity/NatsCapabilityInventory.cs
Step 1: Write the failing test
[Fact]
public void Strict_capability_inventory_has_no_open_items_marked_done_without_behavior_and_tests()
{
var report = NatsCapabilityInventory.Load(
"docs/plans/2026-02-23-nats-strict-full-go-parity-map.md");
report.InvalidRows.ShouldBeEmpty();
}
Step 2: Run test to verify it fails
Run: dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~NatsStrictCapabilityInventoryTests" -v minimal
Expected: FAIL because inventory map and validator are not yet present.
Step 3: Write minimal implementation
public sealed record CapabilityRow(string Capability, string Behavior, string Tests, string Docs);
public IReadOnlyList<CapabilityRow> InvalidRows => Rows.Where(r => r.Behavior != "done" && r.Docs == "closed").ToArray();
Step 4: Run test to verify it passes
Run: dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~NatsStrictCapabilityInventoryTests" -v minimal
Expected: PASS.
Step 5: Commit
git add docs/plans/2026-02-23-nats-strict-full-go-parity-map.md tests/NATS.Server.Tests/Parity/NatsStrictCapabilityInventoryTests.cs tests/NATS.Server.Tests/Parity/NatsCapabilityInventory.cs
git commit -m "test: add strict nats capability inventory guardrail"
Task 2: Enforce Account-Scoped Remote Delivery
Files:
- Modify:
src/NATS.Server/NatsServer.cs - Modify:
src/NATS.Server/Auth/Account.cs - Test:
tests/NATS.Server.Tests/Routes/RouteAccountScopedDeliveryTests.cs - Test:
tests/NATS.Server.Tests/Gateways/GatewayAccountScopedDeliveryTests.cs - Test:
tests/NATS.Server.Tests/LeafNodes/LeafAccountScopedDeliveryTests.cs
Step 1: Write the failing test
[Fact]
public async Task Remote_message_delivery_uses_target_account_sublist_not_global_sublist()
{
await using var fx = await InterServerAccountDeliveryFixture.StartAsync();
var report = await fx.PublishAndObserveAsync();
report.CrossAccountLeak.ShouldBeFalse();
}
Step 2: Run test to verify it fails
Run: dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~AccountScopedDeliveryTests" -v minimal
Expected: FAIL because remote delivery currently resolves against global account only.
Step 3: Write minimal implementation
private void DeliverRemoteMessage(string account, string subject, string? replyTo, ReadOnlyMemory<byte> payload)
{
var target = GetOrCreateAccount(account);
var result = target.SubList.Match(subject);
// deliver using result...
}
Step 4: Run test to verify it passes
Run: dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~AccountScopedDeliveryTests" -v minimal
Expected: PASS.
Step 5: Commit
git add src/NATS.Server/NatsServer.cs src/NATS.Server/Auth/Account.cs tests/NATS.Server.Tests/Routes/RouteAccountScopedDeliveryTests.cs tests/NATS.Server.Tests/Gateways/GatewayAccountScopedDeliveryTests.cs tests/NATS.Server.Tests/LeafNodes/LeafAccountScopedDeliveryTests.cs
git commit -m "feat: enforce account-scoped remote delivery semantics"
Task 3: Make Remote Interest Propagation Idempotent Under Reconnects
Files:
- Modify:
src/NATS.Server/Routes/RouteConnection.cs - Modify:
src/NATS.Server/Routes/RouteManager.cs - Modify:
src/NATS.Server/Gateways/GatewayConnection.cs - Modify:
src/NATS.Server/LeafNodes/LeafConnection.cs - Modify:
src/NATS.Server/Subscriptions/SubList.cs - Test:
tests/NATS.Server.Tests/Routes/RouteInterestIdempotencyTests.cs - Test:
tests/NATS.Server.Tests/Gateways/GatewayInterestIdempotencyTests.cs - Test:
tests/NATS.Server.Tests/LeafNodes/LeafInterestIdempotencyTests.cs
Step 1: Write the failing test
[Fact]
public async Task Duplicate_RSplus_or_reconnect_replay_does_not_double_count_remote_interest()
{
await using var fx = await RouteInterestFixture.StartAsync();
var count = await fx.ReplayInterestFramesAsync();
count.ShouldBe(1);
}
Step 2: Run test to verify it fails
Run: dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~InterestIdempotencyTests" -v minimal
Expected: FAIL due duplicate remote-interest accumulation.
Step 3: Write minimal implementation
// Key remote interest by (remoteServerId, account, subject, queue)
// and treat replay as upsert rather than increment.
Step 4: Run test to verify it passes
Run: dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~InterestIdempotencyTests" -v minimal
Expected: PASS.
Step 5: Commit
git add src/NATS.Server/Routes/RouteConnection.cs src/NATS.Server/Routes/RouteManager.cs src/NATS.Server/Gateways/GatewayConnection.cs src/NATS.Server/LeafNodes/LeafConnection.cs src/NATS.Server/Subscriptions/SubList.cs tests/NATS.Server.Tests/Routes/RouteInterestIdempotencyTests.cs tests/NATS.Server.Tests/Gateways/GatewayInterestIdempotencyTests.cs tests/NATS.Server.Tests/LeafNodes/LeafInterestIdempotencyTests.cs
git commit -m "feat: make inter-server interest propagation idempotent"
Task 4: Harden Gateway Reply Remap and Leaf Loop-Marker Transparency
Files:
- Modify:
src/NATS.Server/Gateways/ReplyMapper.cs - Modify:
src/NATS.Server/LeafNodes/LeafLoopDetector.cs - Modify:
src/NATS.Server/NatsServer.cs - Test:
tests/NATS.Server.Tests/GatewayAdvancedRemapRuntimeTests.cs - Test:
tests/NATS.Server.Tests/LeafNodes/LeafLoopTransparencyRuntimeTests.cs
Step 1: Write the failing test
[Fact]
public async Task Transport_internal_reply_and_loop_markers_never_leak_to_client_visible_subjects()
{
await using var fx = await GatewayLeafMarkerFixture.StartAsync();
var leak = await fx.PublishObserveLeakAsync();
leak.ShouldBeFalse();
}
Step 2: Run test to verify it fails
Run: dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~RemapRuntimeTests|FullyQualifiedName~LoopTransparencyRuntimeTests" -v minimal
Expected: FAIL if markers can leak on edge routing paths.
Step 3: Write minimal implementation
if (ReplyMapper.TryRestoreGatewayReply(replyTo, out var restored)) replyTo = restored;
if (LeafLoopDetector.TryUnmark(subject, out var unmarked)) subject = unmarked;
Step 4: Run test to verify it passes
Run: dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~RemapRuntimeTests|FullyQualifiedName~LoopTransparencyRuntimeTests" -v minimal
Expected: PASS.
Step 5: Commit
git add src/NATS.Server/Gateways/ReplyMapper.cs src/NATS.Server/LeafNodes/LeafLoopDetector.cs src/NATS.Server/NatsServer.cs tests/NATS.Server.Tests/GatewayAdvancedRemapRuntimeTests.cs tests/NATS.Server.Tests/LeafNodes/LeafLoopTransparencyRuntimeTests.cs
git commit -m "feat: harden gateway reply remap and leaf loop transparency"
Task 5: Replace Line-Based MQTT With Packet-Level Parser/Writer
Files:
- Create:
src/NATS.Server/Mqtt/MqttPacketReader.cs - Create:
src/NATS.Server/Mqtt/MqttPacketWriter.cs - Modify:
src/NATS.Server/Mqtt/MqttProtocolParser.cs - Test:
tests/NATS.Server.Tests/Mqtt/MqttPacketParserTests.cs - Test:
tests/NATS.Server.Tests/Mqtt/MqttPacketWriterTests.cs
Step 1: Write the failing test
[Fact]
public void Connect_packet_fixed_header_and_remaining_length_parse_correctly()
{
var packet = MqttPacketReader.Read(ConnectPacketBytes.Sample);
packet.Type.ShouldBe(MqttControlPacketType.Connect);
}
Step 2: Run test to verify it fails
Run: dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~MqttPacketParserTests|FullyQualifiedName~MqttPacketWriterTests" -v minimal
Expected: FAIL because packet-level parser/writer do not yet exist.
Step 3: Write minimal implementation
var first = buffer[0];
var type = (MqttControlPacketType)(first >> 4);
var remainingLength = DecodeRemainingLength(buffer[1..], out var consumed);
Step 4: Run test to verify it passes
Run: dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~MqttPacketParserTests|FullyQualifiedName~MqttPacketWriterTests" -v minimal
Expected: PASS.
Step 5: Commit
git add src/NATS.Server/Mqtt/MqttPacketReader.cs src/NATS.Server/Mqtt/MqttPacketWriter.cs src/NATS.Server/Mqtt/MqttProtocolParser.cs tests/NATS.Server.Tests/Mqtt/MqttPacketParserTests.cs tests/NATS.Server.Tests/Mqtt/MqttPacketWriterTests.cs
git commit -m "feat: implement mqtt packet-level parser and writer"
Task 6: Implement MQTT Session and QoS Acknowledgement Runtime
Files:
- Modify:
src/NATS.Server/Mqtt/MqttConnection.cs - Modify:
src/NATS.Server/Mqtt/MqttListener.cs - Modify:
src/NATS.Server/MqttOptions.cs - Test:
tests/NATS.Server.Tests/Mqtt/MqttSessionRuntimeTests.cs - Test:
tests/NATS.Server.Tests/Mqtt/MqttQosAckRuntimeTests.cs
Step 1: Write the failing test
[Fact]
public async Task Qos1_publish_receives_puback_and_redelivery_on_session_reconnect_when_unacked()
{
await using var fx = await MqttSessionFixture.StartAsync();
var report = await fx.RunQosScenarioAsync();
report.PubAckObserved.ShouldBeTrue();
}
Step 2: Run test to verify it fails
Run: dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~MqttSessionRuntimeTests|FullyQualifiedName~MqttQosAckRuntimeTests" -v minimal
Expected: FAIL because current MQTT runtime lacks session/QoS state machine behavior.
Step 3: Write minimal implementation
if (packet.Qos == 1)
{
_pendingPublishes[packet.PacketId] = packet;
await SendPubAckAsync(packet.PacketId, ct);
}
Step 4: Run test to verify it passes
Run: dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~MqttSessionRuntimeTests|FullyQualifiedName~MqttQosAckRuntimeTests" -v minimal
Expected: PASS.
Step 5: Commit
git add src/NATS.Server/Mqtt/MqttConnection.cs src/NATS.Server/Mqtt/MqttListener.cs src/NATS.Server/MqttOptions.cs tests/NATS.Server.Tests/Mqtt/MqttSessionRuntimeTests.cs tests/NATS.Server.Tests/Mqtt/MqttQosAckRuntimeTests.cs
git commit -m "feat: implement mqtt session and qos ack runtime semantics"
Task 7: Implement MQTT Auth/TLS/Keepalive Contract Integration
Files:
- Modify:
src/NATS.Server/Mqtt/MqttConnection.cs - Modify:
src/NATS.Server/Mqtt/MqttListener.cs - Modify:
src/NATS.Server/NatsServer.cs - Modify:
src/NATS.Server/Auth/AuthService.cs - Test:
tests/NATS.Server.Tests/Mqtt/MqttAuthIntegrationTests.cs - Test:
tests/NATS.Server.Tests/Mqtt/MqttKeepAliveTests.cs
Step 1: Write the failing test
[Fact]
public async Task Invalid_mqtt_credentials_or_keepalive_timeout_close_session_with_protocol_error()
{
await using var fx = await MqttAuthFixture.StartAsync();
var result = await fx.RunInvalidAuthAndKeepAliveScenarioAsync();
result.ConnectionClosed.ShouldBeTrue();
}
Step 2: Run test to verify it fails
Run: dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~MqttAuthIntegrationTests|FullyQualifiedName~MqttKeepAliveTests" -v minimal
Expected: FAIL because MQTT auth and keepalive are not fully enforced.
Step 3: Write minimal implementation
if (!TryAuthenticateMqtt(connectPacket, out _))
return await CloseWithReasonAsync("mqtt auth failed", ct);
Step 4: Run test to verify it passes
Run: dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~MqttAuthIntegrationTests|FullyQualifiedName~MqttKeepAliveTests" -v minimal
Expected: PASS.
Step 5: Commit
git add src/NATS.Server/Mqtt/MqttConnection.cs src/NATS.Server/Mqtt/MqttListener.cs src/NATS.Server/NatsServer.cs src/NATS.Server/Auth/AuthService.cs tests/NATS.Server.Tests/Mqtt/MqttAuthIntegrationTests.cs tests/NATS.Server.Tests/Mqtt/MqttKeepAliveTests.cs
git commit -m "feat: enforce mqtt auth tls and keepalive semantics"
Task 8: Implement Distinct JetStream Retention Runtime Semantics
Files:
- Modify:
src/NATS.Server/JetStream/StreamManager.cs - Modify:
src/NATS.Server/JetStream/ConsumerManager.cs - Test:
tests/NATS.Server.Tests/JetStream/JetStreamRetentionRuntimeStrictParityTests.cs
Step 1: Write the failing test
[Fact]
public async Task Limits_interest_and_workqueue_retention_diverge_by_runtime_contract()
{
await using var fx = await JetStreamRetentionStrictFixture.StartAsync();
var report = await fx.RunPolicyMatrixAsync();
report.PolicyViolations.ShouldBeEmpty();
}
Step 2: Run test to verify it fails
Run: dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~JetStreamRetentionRuntimeStrictParityTests" -v minimal
Expected: FAIL because WorkQueue/Interest currently share limits retention path.
Step 3: Write minimal implementation
switch (stream.Config.Retention)
{
case RetentionPolicy.Interest: ApplyInterestRetentionWithConsumerInterest(stream, consumerState); break;
case RetentionPolicy.WorkQueue: ApplyWorkQueueRetentionWithAckState(stream, consumerState); break;
default: ApplyLimitsRetention(stream, nowUtc); break;
}
Step 4: Run test to verify it passes
Run: dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~JetStreamRetentionRuntimeStrictParityTests" -v minimal
Expected: PASS.
Step 5: Commit
git add src/NATS.Server/JetStream/StreamManager.cs src/NATS.Server/JetStream/ConsumerManager.cs tests/NATS.Server.Tests/JetStream/JetStreamRetentionRuntimeStrictParityTests.cs
git commit -m "feat: implement strict retention runtime parity for jetstream"
Task 9: Harden JetStream Consumer Ack/Backoff/Replay/Flow State Machine
Files:
- Modify:
src/NATS.Server/JetStream/Consumers/AckProcessor.cs - Modify:
src/NATS.Server/JetStream/Consumers/PullConsumerEngine.cs - Modify:
src/NATS.Server/JetStream/Consumers/PushConsumerEngine.cs - Modify:
src/NATS.Server/JetStream/ConsumerManager.cs - Test:
tests/NATS.Server.Tests/JetStream/JetStreamConsumerStateMachineStrictParityTests.cs
Step 1: Write the failing test
[Fact]
public async Task Ack_redelivery_backoff_and_replay_timing_follow_monotonic_consumer_state_machine_rules()
{
await using var fx = await ConsumerStateMachineFixture.StartAsync();
var report = await fx.RunLongScenarioAsync();
report.InvariantViolations.ShouldBeEmpty();
}
Step 2: Run test to verify it fails
Run: dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~JetStreamConsumerStateMachineStrictParityTests" -v minimal
Expected: FAIL on pending-floor/replay/backoff edge cases.
Step 3: Write minimal implementation
if (config.MaxDeliver > 0 && deliveries > config.MaxDeliver) TerminatePending(sequence);
if (config.AckPolicy == AckPolicy.All) AdvanceAckFloor(sequence);
Step 4: Run test to verify it passes
Run: dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~JetStreamConsumerStateMachineStrictParityTests" -v minimal
Expected: PASS.
Step 5: Commit
git add src/NATS.Server/JetStream/Consumers/AckProcessor.cs src/NATS.Server/JetStream/Consumers/PullConsumerEngine.cs src/NATS.Server/JetStream/Consumers/PushConsumerEngine.cs src/NATS.Server/JetStream/ConsumerManager.cs tests/NATS.Server.Tests/JetStream/JetStreamConsumerStateMachineStrictParityTests.cs
git commit -m "feat: harden jetstream consumer state machine parity"
Task 10: Harden JetStream Mirror/Source Runtime Semantics
Files:
- Modify:
src/NATS.Server/JetStream/StreamManager.cs - Modify:
src/NATS.Server/JetStream/MirrorSource/MirrorCoordinator.cs - Modify:
src/NATS.Server/JetStream/MirrorSource/SourceCoordinator.cs - Test:
tests/NATS.Server.Tests/JetStream/JetStreamMirrorSourceStrictRuntimeTests.cs
Step 1: Write the failing test
[Fact]
public async Task Mirror_source_transform_and_cross_account_filters_follow_runtime_contract()
{
await using var fx = await MirrorSourceStrictFixture.StartAsync();
var report = await fx.RunScenarioAsync();
report.InvariantViolations.ShouldBeEmpty();
}
Step 2: Run test to verify it fails
Run: dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~JetStreamMirrorSourceStrictRuntimeTests" -v minimal
Expected: FAIL for cross-account and filter-transform edge combinations.
Step 3: Write minimal implementation
if (!SourceAccountAuthorized(sourceConfig, message.Account)) return;
if (!FilterMatches(sourceConfig, message.Subject)) return;
Step 4: Run test to verify it passes
Run: dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~JetStreamMirrorSourceStrictRuntimeTests" -v minimal
Expected: PASS.
Step 5: Commit
git add src/NATS.Server/JetStream/StreamManager.cs src/NATS.Server/JetStream/MirrorSource/MirrorCoordinator.cs src/NATS.Server/JetStream/MirrorSource/SourceCoordinator.cs tests/NATS.Server.Tests/JetStream/JetStreamMirrorSourceStrictRuntimeTests.cs
git commit -m "feat: complete jetstream mirror source strict runtime parity"
Task 11: Implement FileStore Durable Invariants and Recovery Contract
Files:
- Modify:
src/NATS.Server/JetStream/Storage/FileStore.cs - Modify:
src/NATS.Server/JetStream/Storage/FileStoreBlock.cs - Test:
tests/NATS.Server.Tests/JetStream/JetStreamFileStoreRecoveryStrictParityTests.cs - Test:
tests/NATS.Server.Tests/JetStream/JetStreamFileStoreInvariantTests.cs
Step 1: Write the failing test
[Fact]
public async Task Filestore_recovery_preserves_sequence_subject_index_and_integrity_after_prune_and_restart_cycles()
{
var report = await FileStoreStrictFixture.RunRecoveryCycleAsync();
report.InvariantViolations.ShouldBeEmpty();
}
Step 2: Run test to verify it fails
Run: dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~JetStreamFileStoreRecoveryStrictParityTests|FullyQualifiedName~JetStreamFileStoreInvariantTests" -v minimal
Expected: FAIL on restart/prune/index invariant checks.
Step 3: Write minimal implementation
PersistManifestVersioned();
ValidateSequenceAndSubjectIndexOnLoad();
Step 4: Run test to verify it passes
Run: dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~JetStreamFileStoreRecoveryStrictParityTests|FullyQualifiedName~JetStreamFileStoreInvariantTests" -v minimal
Expected: PASS.
Step 5: Commit
git add src/NATS.Server/JetStream/Storage/FileStore.cs src/NATS.Server/JetStream/Storage/FileStoreBlock.cs tests/NATS.Server.Tests/JetStream/JetStreamFileStoreRecoveryStrictParityTests.cs tests/NATS.Server.Tests/JetStream/JetStreamFileStoreInvariantTests.cs
git commit -m "feat: enforce filestore durability and recovery invariants"
Task 12: Implement RAFT Quorum/NextIndex/Snapshot/Membership Runtime Semantics
Files:
- Modify:
src/NATS.Server/Raft/RaftNode.cs - Modify:
src/NATS.Server/Raft/RaftReplicator.cs - Modify:
src/NATS.Server/Raft/RaftTransport.cs - Modify:
src/NATS.Server/Raft/RaftSnapshotStore.cs - Test:
tests/NATS.Server.Tests/Raft/RaftStrictConsensusRuntimeTests.cs - Test:
tests/NATS.Server.Tests/Raft/RaftStrictConvergenceRuntimeTests.cs
Step 1: Write the failing test
[Fact]
public async Task Quorum_and_nextindex_rules_gate_commit_visibility_and_snapshot_catchup_convergence()
{
var report = await RaftStrictFixture.RunConsensusScenarioAsync();
report.InvariantViolations.ShouldBeEmpty();
}
Step 2: Run test to verify it fails
Run: dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~RaftStrictConsensusRuntimeTests|FullyQualifiedName~RaftStrictConvergenceRuntimeTests" -v minimal
Expected: FAIL due simplified in-memory quorum and convergence behavior.
Step 3: Write minimal implementation
if (!HasQuorum(appendAcks)) return CommitRejected();
nextIndex[follower] = ComputeNextIndexOnMismatch(followerState);
Step 4: Run test to verify it passes
Run: dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~RaftStrictConsensusRuntimeTests|FullyQualifiedName~RaftStrictConvergenceRuntimeTests" -v minimal
Expected: PASS.
Step 5: Commit
git add src/NATS.Server/Raft/RaftNode.cs src/NATS.Server/Raft/RaftReplicator.cs src/NATS.Server/Raft/RaftTransport.cs src/NATS.Server/Raft/RaftSnapshotStore.cs tests/NATS.Server.Tests/Raft/RaftStrictConsensusRuntimeTests.cs tests/NATS.Server.Tests/Raft/RaftStrictConvergenceRuntimeTests.cs
git commit -m "feat: implement strict raft consensus and convergence parity"
Task 13: Implement JetStream Meta/Replica Governance Runtime Contracts
Files:
- Modify:
src/NATS.Server/JetStream/Cluster/JetStreamMetaGroup.cs - Modify:
src/NATS.Server/JetStream/Cluster/StreamReplicaGroup.cs - Modify:
src/NATS.Server/JetStream/StreamManager.cs - Test:
tests/NATS.Server.Tests/JetStream/JetStreamMetaGovernanceStrictParityTests.cs - Test:
tests/NATS.Server.Tests/JetStream/JetStreamReplicaGovernanceStrictParityTests.cs
Step 1: Write the failing test
[Fact]
public async Task Meta_and_replica_governance_actions_reflect_committed_state_transitions()
{
await using var fx = await JetStreamGovernanceFixture.StartAsync();
var report = await fx.RunStepdownPlacementScenarioAsync();
report.InvariantViolations.ShouldBeEmpty();
}
Step 2: Run test to verify it fails
Run: dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~JetStreamMetaGovernanceStrictParityTests|FullyQualifiedName~JetStreamReplicaGovernanceStrictParityTests" -v minimal
Expected: FAIL due placeholder governance behavior.
Step 3: Write minimal implementation
public void StepDown() => _leaderId = ElectNextLeader();
Step 4: Run test to verify it passes
Run: dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~JetStreamMetaGovernanceStrictParityTests|FullyQualifiedName~JetStreamReplicaGovernanceStrictParityTests" -v minimal
Expected: PASS.
Step 5: Commit
git add src/NATS.Server/JetStream/Cluster/JetStreamMetaGroup.cs src/NATS.Server/JetStream/Cluster/StreamReplicaGroup.cs src/NATS.Server/JetStream/StreamManager.cs tests/NATS.Server.Tests/JetStream/JetStreamMetaGovernanceStrictParityTests.cs tests/NATS.Server.Tests/JetStream/JetStreamReplicaGovernanceStrictParityTests.cs
git commit -m "feat: implement jetstream governance runtime parity semantics"
Task 14: Replace Synthetic Profiling and Close Runtime Option Drift
Files:
- Modify:
src/NATS.Server/Monitoring/PprofHandler.cs - Modify:
src/NATS.Server/Monitoring/MonitorServer.cs - Modify:
src/NATS.Server/NatsServer.cs - Modify:
src/NATS.Server/Configuration/ConfigReloader.cs - Test:
tests/NATS.Server.Tests/Monitoring/PprofRuntimeParityTests.cs - Test:
tests/NATS.Server.Tests/ConfigRuntimeParityTests.cs
Step 1: Write the failing test
[Fact]
public async Task Profiling_endpoint_returns_runtime_profile_artifacts_and_config_options_map_to_runtime_behavior()
{
var report = await OperationalParityFixture.RunAsync();
report.InvariantViolations.ShouldBeEmpty();
}
Step 2: Run test to verify it fails
Run: dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~PprofRuntimeParityTests|FullyQualifiedName~ConfigRuntimeParityTests" -v minimal
Expected: FAIL due synthetic profiling output and option-runtime mismatches.
Step 3: Write minimal implementation
public byte[] CaptureCpuProfile(int seconds) => _runtimeProfiler.Capture(seconds);
Step 4: Run test to verify it passes
Run: dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~PprofRuntimeParityTests|FullyQualifiedName~ConfigRuntimeParityTests" -v minimal
Expected: PASS.
Step 5: Commit
git add src/NATS.Server/Monitoring/PprofHandler.cs src/NATS.Server/Monitoring/MonitorServer.cs src/NATS.Server/NatsServer.cs src/NATS.Server/Configuration/ConfigReloader.cs tests/NATS.Server.Tests/Monitoring/PprofRuntimeParityTests.cs tests/NATS.Server.Tests/ConfigRuntimeParityTests.cs
git commit -m "feat: add runtime profiling parity and close config runtime drift"
Task 15: Final Verification and Documentation Synchronization
Files:
- Modify:
differences.md - Modify:
docs/plans/2026-02-23-jetstream-remaining-parity-map.md - Modify:
docs/plans/2026-02-23-jetstream-remaining-parity-verification.md - Modify:
docs/plans/2026-02-23-nats-strict-full-go-parity-map.md - Modify:
tests/NATS.Server.Tests/DifferencesParityClosureTests.cs
Step 1: Write the failing test
[Fact]
public void Differences_and_strict_capability_maps_have_no_claims_without_behavior_and_test_evidence()
{
var report = StrictParityDocInspector.Load("differences.md", "docs/plans/2026-02-23-nats-strict-full-go-parity-map.md");
report.DriftRows.ShouldBeEmpty();
}
Step 2: Run test to verify it fails
Run: dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~DifferencesParityClosureTests|FullyQualifiedName~NatsStrictCapabilityInventoryTests" -v minimal
Expected: FAIL until docs are synchronized with implemented behavior.
Step 3: Update parity docs and evidence maps
Run: rg -n "remaining|incomplete|baseline|stub|placeholder" differences.md docs/plans/2026-02-23-nats-strict-full-go-parity-map.md
Expected: only intentionally deferred items remain and each has explicit blocker rationale.
Step 4: Run full verification
Run: dotnet test -v minimal
Expected: PASS.
Step 5: Commit
git add differences.md docs/plans/2026-02-23-jetstream-remaining-parity-map.md docs/plans/2026-02-23-jetstream-remaining-parity-verification.md docs/plans/2026-02-23-nats-strict-full-go-parity-map.md tests/NATS.Server.Tests/DifferencesParityClosureTests.cs
git commit -m "docs: synchronize strict full go parity evidence and status"
Plan Notes
- Prefer small, behavior-focused deltas in each task.
- Do not mark any capability as closed based on type signatures, placeholders, or route registration alone.
- Keep runtime integration fixtures deterministic and timeout-bounded to avoid flaky parity claims.