docs: add full-repo remaining parity plan

This commit is contained in:
Joseph Doherty
2026-02-23 12:24:29 -05:00
parent 6d2bfc0660
commit cbe1fa6121

View File

@@ -0,0 +1,923 @@
# Full-Repo Remaining Parity Implementation Plan
> **For Codex:** REQUIRED SUB-SKILL: Use `executeplan` to implement this plan task-by-task.
**Goal:** Close every currently unresolved `Baseline` / `N` / `Stub` parity row in `differences.md` with strict behavior-level parity and test-backed evidence.
**Architecture:** Use a truth-matrix workflow where each unresolved row is tracked by behavior, test, and docs state. Implement dependencies in layers: core server/protocol/sublist first, then auth/monitoring, then JetStream runtime/storage/RAFT/clustering, then docs synchronization. Rows move to `Y` only when behavior is implemented and validated by meaningful contract tests.
**Tech Stack:** .NET 10, C# 14, xUnit 3, Shouldly, ASP.NET Core minimal APIs, System.IO.Pipelines, System.Buffers, System.Text.Json.
---
**Execution guardrails**
- Use `@test-driven-development` for every task.
- If behavior diverges from protocol/runtime expectations, switch to `@systematic-debugging` before code changes.
- Keep one commit per task.
- Run `@verification-before-completion` before final status updates.
### Task 1: Add Truth-Matrix Parity Guard and Fix Summary/Table Drift Detection
**Files:**
- Modify: `tests/NATS.Server.Tests/DifferencesParityClosureTests.cs`
- Create: `tests/NATS.Server.Tests/Parity/ParityRowInspector.cs`
- Modify: `differences.md`
**Step 1: Write the failing test**
```csharp
[Fact]
public void Differences_md_has_no_remaining_baseline_n_or_stub_rows_in_tracked_scope()
{
var report = ParityRowInspector.Load("differences.md");
report.UnresolvedRows.ShouldBeEmpty();
}
```
**Step 2: Run test to verify it fails**
Run: `dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~DifferencesParityClosureTests" -v minimal`
Expected: FAIL with unresolved rows list from table entries (not summary prose).
**Step 3: Write minimal implementation**
```csharp
public sealed record ParityRow(string Section, string SubSection, string Feature, string DotNetStatus);
public IReadOnlyList<ParityRow> UnresolvedRows => Rows.Where(r => r.DotNetStatus is "N" or "Baseline" or "Stub").ToArray();
```
**Step 4: Run test to verify it passes**
Run: `dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~DifferencesParityClosureTests" -v minimal`
Expected: PASS once unresolved rows are fully closed at end of plan.
**Step 5: Commit**
```bash
git add tests/NATS.Server.Tests/DifferencesParityClosureTests.cs tests/NATS.Server.Tests/Parity/ParityRowInspector.cs differences.md
git commit -m "test: enforce row-level parity closure from differences table"
```
### Task 2: Implement Profiling Endpoint (`/debug/pprof`) Support
**Files:**
- Modify: `src/NATS.Server/NatsServer.cs`
- Modify: `src/NATS.Server/Monitoring/MonitorServer.cs`
- Create: `src/NATS.Server/Monitoring/PprofHandler.cs`
- Test: `tests/NATS.Server.Tests/Monitoring/PprofEndpointTests.cs`
**Step 1: Write the failing test**
```csharp
[Fact]
public async Task Debug_pprof_endpoint_returns_profile_index_when_profport_enabled()
{
await using var fx = await MonitorFixture.StartWithProfilingAsync();
var body = await fx.GetStringAsync("/debug/pprof");
body.ShouldContain("profiles");
}
```
**Step 2: Run test to verify it fails**
Run: `dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~PprofEndpointTests" -v minimal`
Expected: FAIL with 404 or endpoint missing.
**Step 3: Write minimal implementation**
```csharp
app.MapGet("/debug/pprof", (PprofHandler h) => Results.Text(h.Index(), "text/plain"));
app.MapGet("/debug/pprof/profile", (PprofHandler h, int seconds) => Results.File(h.CaptureCpuProfile(seconds), "application/octet-stream"));
```
**Step 4: Run test to verify it passes**
Run: `dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~PprofEndpointTests" -v minimal`
Expected: PASS.
**Step 5: Commit**
```bash
git add src/NATS.Server/NatsServer.cs src/NATS.Server/Monitoring/MonitorServer.cs src/NATS.Server/Monitoring/PprofHandler.cs tests/NATS.Server.Tests/Monitoring/PprofEndpointTests.cs
git commit -m "feat: add profiling endpoint parity support"
```
### Task 3: Add Accept-Loop Reload Lock and Callback Error Hook Parity
**Files:**
- Modify: `src/NATS.Server/NatsServer.cs`
- Modify: `src/NATS.Server/Configuration/ConfigReloader.cs`
- Create: `src/NATS.Server/Server/AcceptLoopErrorHandler.cs`
- Test: `tests/NATS.Server.Tests/Server/AcceptLoopReloadLockTests.cs`
- Test: `tests/NATS.Server.Tests/Server/AcceptLoopErrorCallbackTests.cs`
**Step 1: Write the failing test**
```csharp
[Fact]
public async Task Accept_loop_blocks_client_creation_while_reload_lock_is_held()
{
await using var fx = await AcceptLoopFixture.StartAsync();
await fx.HoldReloadLockAsync();
(await fx.TryConnectClientAsync(timeoutMs: 150)).ShouldBeFalse();
}
```
**Step 2: Run test to verify it fails**
Run: `dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~AcceptLoopReloadLockTests|FullyQualifiedName~AcceptLoopErrorCallbackTests" -v minimal`
Expected: FAIL because create-client path does not acquire reload lock and has no callback-based hook.
**Step 3: Write minimal implementation**
```csharp
await _reloadMu.WaitAsync(ct);
try { await CreateClientAsync(socket, ct); }
finally { _reloadMu.Release(); }
```
```csharp
_errorHandler?.OnAcceptError(ex, endpoint, delay);
```
**Step 4: Run test to verify it passes**
Run: `dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~AcceptLoopReloadLockTests|FullyQualifiedName~AcceptLoopErrorCallbackTests" -v minimal`
Expected: PASS.
**Step 5: Commit**
```bash
git add src/NATS.Server/NatsServer.cs src/NATS.Server/Configuration/ConfigReloader.cs src/NATS.Server/Server/AcceptLoopErrorHandler.cs tests/NATS.Server.Tests/Server/AcceptLoopReloadLockTests.cs tests/NATS.Server.Tests/Server/AcceptLoopErrorCallbackTests.cs
git commit -m "feat: add accept-loop reload lock and error callback parity"
```
### Task 4: Implement Dynamic Buffer Sizing and 3-Tier Output Buffer Pooling
**Files:**
- Modify: `src/NATS.Server/NatsClient.cs`
- Create: `src/NATS.Server/IO/AdaptiveReadBuffer.cs`
- Create: `src/NATS.Server/IO/OutboundBufferPool.cs`
- Test: `tests/NATS.Server.Tests/IO/AdaptiveReadBufferTests.cs`
- Test: `tests/NATS.Server.Tests/IO/OutboundBufferPoolTests.cs`
**Step 1: Write the failing test**
```csharp
[Fact]
public void Read_buffer_scales_between_512_and_65536_based_on_recent_payload_pattern()
{
var b = new AdaptiveReadBuffer();
b.RecordRead(512); b.RecordRead(4096); b.RecordRead(32000);
b.CurrentSize.ShouldBeGreaterThan(4096);
}
```
**Step 2: Run test to verify it fails**
Run: `dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~AdaptiveReadBufferTests|FullyQualifiedName~OutboundBufferPoolTests" -v minimal`
Expected: FAIL because no adaptive model or 3-tier pool exists.
**Step 3: Write minimal implementation**
```csharp
public int CurrentSize => Math.Clamp(_target, 512, 64 * 1024);
public IMemoryOwner<byte> Rent(int size) => size <= 512 ? _small.Rent(512) : size <= 4096 ? _medium.Rent(4096) : _large.Rent(64 * 1024);
```
**Step 4: Run test to verify it passes**
Run: `dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~AdaptiveReadBufferTests|FullyQualifiedName~OutboundBufferPoolTests" -v minimal`
Expected: PASS.
**Step 5: Commit**
```bash
git add src/NATS.Server/NatsClient.cs src/NATS.Server/IO/AdaptiveReadBuffer.cs src/NATS.Server/IO/OutboundBufferPool.cs tests/NATS.Server.Tests/IO/AdaptiveReadBufferTests.cs tests/NATS.Server.Tests/IO/OutboundBufferPoolTests.cs
git commit -m "feat: add adaptive read buffers and outbound buffer pooling"
```
### Task 5: Unify Inter-Server Opcode Semantics With Client-Kind Routing and Trace Initialization
**Files:**
- Modify: `src/NATS.Server/Protocol/NatsParser.cs`
- Modify: `src/NATS.Server/Protocol/ClientCommandMatrix.cs`
- Modify: `src/NATS.Server/NatsClient.cs`
- Modify: `src/NATS.Server/Routes/RouteConnection.cs`
- Modify: `src/NATS.Server/Gateways/GatewayConnection.cs`
- Modify: `src/NATS.Server/LeafNodes/LeafConnection.cs`
- Test: `tests/NATS.Server.Tests/Protocol/InterServerOpcodeRoutingTests.cs`
- Test: `tests/NATS.Server.Tests/Protocol/MessageTraceInitializationTests.cs`
**Step 1: Write the failing test**
```csharp
[Fact]
public void Parser_dispatch_rejects_Aplus_for_client_kind_client_but_allows_for_gateway()
{
var m = new ClientCommandMatrix();
m.IsAllowed(ClientKind.Client, "A+").ShouldBeFalse();
m.IsAllowed(ClientKind.Gateway, "A+").ShouldBeTrue();
}
```
**Step 2: Run test to verify it fails**
Run: `dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~InterServerOpcodeRoutingTests|FullyQualifiedName~MessageTraceInitializationTests" -v minimal`
Expected: FAIL due incomplete parser/dispatch trace-init parity.
**Step 3: Write minimal implementation**
```csharp
if (!CommandMatrix.IsAllowed(kind, op))
throw new ProtocolViolationException($"operation {op} not allowed for {kind}");
```
```csharp
_traceContext = MessageTraceContext.CreateFromConnect(connectOpts);
```
**Step 4: Run test to verify it passes**
Run: `dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~InterServerOpcodeRoutingTests|FullyQualifiedName~MessageTraceInitializationTests" -v minimal`
Expected: PASS.
**Step 5: Commit**
```bash
git add src/NATS.Server/Protocol/NatsParser.cs src/NATS.Server/Protocol/ClientCommandMatrix.cs src/NATS.Server/NatsClient.cs src/NATS.Server/Routes/RouteConnection.cs src/NATS.Server/Gateways/GatewayConnection.cs src/NATS.Server/LeafNodes/LeafConnection.cs tests/NATS.Server.Tests/Protocol/InterServerOpcodeRoutingTests.cs tests/NATS.Server.Tests/Protocol/MessageTraceInitializationTests.cs
git commit -m "feat: enforce inter-server opcode routing and trace initialization"
```
### Task 6: Implement SubList Missing Features (Notifications, Local/Remote Filters, Queue Weight, MatchBytes)
**Files:**
- Modify: `src/NATS.Server/Subscriptions/SubList.cs`
- Modify: `src/NATS.Server/Subscriptions/RemoteSubscription.cs`
- Modify: `src/NATS.Server/Subscriptions/Subscription.cs`
- Test: `tests/NATS.Server.Tests/SubList/SubListNotificationTests.cs`
- Test: `tests/NATS.Server.Tests/SubList/SubListRemoteFilterTests.cs`
- Test: `tests/NATS.Server.Tests/SubList/SubListQueueWeightTests.cs`
- Test: `tests/NATS.Server.Tests/SubList/SubListMatchBytesTests.cs`
**Step 1: Write the failing test**
```csharp
[Fact]
public void MatchBytes_matches_subject_without_string_allocation_and_respects_remote_filter()
{
var sl = new SubList();
sl.MatchBytes("orders.created"u8.ToArray()).PlainSubs.Length.ShouldBe(0);
}
```
**Step 2: Run test to verify it fails**
Run: `dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~SubListNotificationTests|FullyQualifiedName~SubListRemoteFilterTests|FullyQualifiedName~SubListQueueWeightTests|FullyQualifiedName~SubListMatchBytesTests" -v minimal`
Expected: FAIL because APIs and behavior are missing.
**Step 3: Write minimal implementation**
```csharp
public SubListResult MatchBytes(ReadOnlySpan<byte> subjectUtf8) => Match(Encoding.ASCII.GetString(subjectUtf8));
public event Action<InterestChange>? InterestChanged;
```
```csharp
if (remoteSub.QueueWeight > 0) expanded.AddRange(Enumerable.Repeat(remoteSub, remoteSub.QueueWeight));
```
**Step 4: Run test to verify it passes**
Run: `dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~SubListNotificationTests|FullyQualifiedName~SubListRemoteFilterTests|FullyQualifiedName~SubListQueueWeightTests|FullyQualifiedName~SubListMatchBytesTests" -v minimal`
Expected: PASS.
**Step 5: Commit**
```bash
git add src/NATS.Server/Subscriptions/SubList.cs src/NATS.Server/Subscriptions/RemoteSubscription.cs src/NATS.Server/Subscriptions/Subscription.cs tests/NATS.Server.Tests/SubList/SubListNotificationTests.cs tests/NATS.Server.Tests/SubList/SubListRemoteFilterTests.cs tests/NATS.Server.Tests/SubList/SubListQueueWeightTests.cs tests/NATS.Server.Tests/SubList/SubListMatchBytesTests.cs
git commit -m "feat: add remaining sublist parity behaviors"
```
### Task 7: Add Trie Fanout Optimization and Async Cache Sweep Behavior
**Files:**
- Modify: `src/NATS.Server/Subscriptions/SubList.cs`
- Create: `src/NATS.Server/Subscriptions/SubListCacheSweeper.cs`
- Test: `tests/NATS.Server.Tests/SubList/SubListHighFanoutOptimizationTests.cs`
- Test: `tests/NATS.Server.Tests/SubList/SubListAsyncCacheSweepTests.cs`
**Step 1: Write the failing test**
```csharp
[Fact]
public async Task Cache_sweep_runs_async_and_prunes_stale_entries_without_write_locking_match_path()
{
var fx = await SubListSweepFixture.BuildLargeCacheAsync();
await fx.TriggerSweepAsync();
fx.CacheCount.ShouldBeLessThan(fx.InitialCacheCount);
}
```
**Step 2: Run test to verify it fails**
Run: `dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~SubListHighFanoutOptimizationTests|FullyQualifiedName~SubListAsyncCacheSweepTests" -v minimal`
Expected: FAIL because sweep is currently inline and no high-fanout node optimization exists.
**Step 3: Write minimal implementation**
```csharp
if (node.PlainSubs.Count > 256) node.EnablePackedList();
_sweeper.ScheduleSweep(_cache, generation);
```
**Step 4: Run test to verify it passes**
Run: `dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~SubListHighFanoutOptimizationTests|FullyQualifiedName~SubListAsyncCacheSweepTests" -v minimal`
Expected: PASS.
**Step 5: Commit**
```bash
git add src/NATS.Server/Subscriptions/SubList.cs src/NATS.Server/Subscriptions/SubListCacheSweeper.cs tests/NATS.Server.Tests/SubList/SubListHighFanoutOptimizationTests.cs tests/NATS.Server.Tests/SubList/SubListAsyncCacheSweepTests.cs
git commit -m "feat: add trie fanout optimization and async cache sweep"
```
### Task 8: Complete Route Parity (Account-Specific Routes, Topology Gossip, Route Compression)
**Files:**
- Modify: `src/NATS.Server/Routes/RouteConnection.cs`
- Modify: `src/NATS.Server/Routes/RouteManager.cs`
- Modify: `src/NATS.Server/Configuration/ClusterOptions.cs`
- Test: `tests/NATS.Server.Tests/Routes/RouteAccountScopedTests.cs`
- Test: `tests/NATS.Server.Tests/Routes/RouteTopologyGossipTests.cs`
- Test: `tests/NATS.Server.Tests/Routes/RouteCompressionTests.cs`
**Step 1: Write the failing test**
```csharp
[Fact]
public async Task Route_connect_exchange_includes_account_scope_and_topology_gossip_snapshot()
{
await using var fx = await RouteGossipFixture.StartPairAsync();
var info = await fx.ReadRouteConnectInfoAsync();
info.Accounts.ShouldContain("A");
}
```
**Step 2: Run test to verify it fails**
Run: `dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~RouteAccountScopedTests|FullyQualifiedName~RouteTopologyGossipTests|FullyQualifiedName~RouteCompressionTests" -v minimal`
Expected: FAIL because route handshake is still minimal text and no compression/account-scoped route model.
**Step 3: Write minimal implementation**
```csharp
await WriteLineAsync($"CONNECT {JsonSerializer.Serialize(routeInfo)}", ct);
if (_options.Compression == RouteCompression.S2) payload = S2Codec.Compress(payload);
```
**Step 4: Run test to verify it passes**
Run: `dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~RouteAccountScopedTests|FullyQualifiedName~RouteTopologyGossipTests|FullyQualifiedName~RouteCompressionTests" -v minimal`
Expected: PASS.
**Step 5: Commit**
```bash
git add src/NATS.Server/Routes/RouteConnection.cs src/NATS.Server/Routes/RouteManager.cs src/NATS.Server/Configuration/ClusterOptions.cs tests/NATS.Server.Tests/Routes/RouteAccountScopedTests.cs tests/NATS.Server.Tests/Routes/RouteTopologyGossipTests.cs tests/NATS.Server.Tests/Routes/RouteCompressionTests.cs
git commit -m "feat: complete route account gossip and compression parity"
```
### Task 9: Complete Gateway and Leaf Advanced Semantics (Interest-Only, Hub/Spoke Mapping)
**Files:**
- Modify: `src/NATS.Server/Gateways/GatewayConnection.cs`
- Modify: `src/NATS.Server/Gateways/GatewayManager.cs`
- Modify: `src/NATS.Server/LeafNodes/LeafConnection.cs`
- Modify: `src/NATS.Server/LeafNodes/LeafNodeManager.cs`
- Modify: `src/NATS.Server/NatsServer.cs`
- Test: `tests/NATS.Server.Tests/Gateways/GatewayInterestOnlyParityTests.cs`
- Test: `tests/NATS.Server.Tests/LeafNodes/LeafHubSpokeMappingParityTests.cs`
**Step 1: Write the failing test**
```csharp
[Fact]
public async Task Gateway_interest_only_mode_forwards_only_subjects_with_remote_interest_and_reply_map_roundtrips()
{
await using var fx = await GatewayInterestFixture.StartAsync();
(await fx.ForwardedWithoutInterestCountAsync()).ShouldBe(0);
}
```
**Step 2: Run test to verify it fails**
Run: `dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~GatewayInterestOnlyParityTests|FullyQualifiedName~LeafHubSpokeMappingParityTests" -v minimal`
Expected: FAIL because advanced interest-only and leaf account remap semantics are incomplete.
**Step 3: Write minimal implementation**
```csharp
if (!_interestTable.HasInterest(account, subject)) return;
var mapped = _hubSpokeMapper.Map(account, subject, direction);
```
**Step 4: Run test to verify it passes**
Run: `dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~GatewayInterestOnlyParityTests|FullyQualifiedName~LeafHubSpokeMappingParityTests" -v minimal`
Expected: PASS.
**Step 5: Commit**
```bash
git add src/NATS.Server/Gateways/GatewayConnection.cs src/NATS.Server/Gateways/GatewayManager.cs src/NATS.Server/LeafNodes/LeafConnection.cs src/NATS.Server/LeafNodes/LeafNodeManager.cs src/NATS.Server/NatsServer.cs tests/NATS.Server.Tests/Gateways/GatewayInterestOnlyParityTests.cs tests/NATS.Server.Tests/LeafNodes/LeafHubSpokeMappingParityTests.cs
git commit -m "feat: complete gateway and leaf advanced parity semantics"
```
### Task 10: Add Auth Extension Parity (Custom Interface, External Callout, Proxy Auth)
**Files:**
- Modify: `src/NATS.Server/Auth/AuthService.cs`
- Modify: `src/NATS.Server/Auth/IAuthenticator.cs`
- Create: `src/NATS.Server/Auth/ExternalAuthCalloutAuthenticator.cs`
- Create: `src/NATS.Server/Auth/ProxyAuthenticator.cs`
- Modify: `src/NATS.Server/NatsOptions.cs`
- Test: `tests/NATS.Server.Tests/Auth/AuthExtensionParityTests.cs`
- Test: `tests/NATS.Server.Tests/Auth/ExternalAuthCalloutTests.cs`
- Test: `tests/NATS.Server.Tests/Auth/ProxyAuthTests.cs`
**Step 1: Write the failing test**
```csharp
[Fact]
public async Task External_callout_authenticator_can_allow_and_deny_with_timeout_and_reason_mapping()
{
var result = await AuthExtensionFixture.AuthenticateViaExternalAsync("u", "p");
result.Success.ShouldBeTrue();
}
```
**Step 2: Run test to verify it fails**
Run: `dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~AuthExtensionParityTests|FullyQualifiedName~ExternalAuthCalloutTests|FullyQualifiedName~ProxyAuthTests" -v minimal`
Expected: FAIL because extension points are not wired.
**Step 3: Write minimal implementation**
```csharp
public interface IExternalAuthClient { Task<ExternalAuthDecision> AuthorizeAsync(ExternalAuthRequest req, CancellationToken ct); }
if (_options.ExternalAuth is { Enabled: true }) authenticators.Add(new ExternalAuthCalloutAuthenticator(...));
```
**Step 4: Run test to verify it passes**
Run: `dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~AuthExtensionParityTests|FullyQualifiedName~ExternalAuthCalloutTests|FullyQualifiedName~ProxyAuthTests" -v minimal`
Expected: PASS.
**Step 5: Commit**
```bash
git add src/NATS.Server/Auth/AuthService.cs src/NATS.Server/Auth/IAuthenticator.cs src/NATS.Server/Auth/ExternalAuthCalloutAuthenticator.cs src/NATS.Server/Auth/ProxyAuthenticator.cs src/NATS.Server/NatsOptions.cs tests/NATS.Server.Tests/Auth/AuthExtensionParityTests.cs tests/NATS.Server.Tests/Auth/ExternalAuthCalloutTests.cs tests/NATS.Server.Tests/Auth/ProxyAuthTests.cs
git commit -m "feat: add custom external and proxy authentication parity"
```
### Task 11: Close Monitoring Parity Gaps (`connz` filters/details and missing identity/tls/proxy fields)
**Files:**
- Modify: `src/NATS.Server/Monitoring/ConnzHandler.cs`
- Modify: `src/NATS.Server/Monitoring/Connz.cs`
- Modify: `src/NATS.Server/Monitoring/VarzHandler.cs`
- Modify: `src/NATS.Server/Monitoring/Varz.cs`
- Modify: `src/NATS.Server/Monitoring/ClosedClient.cs`
- Test: `tests/NATS.Server.Tests/Monitoring/ConnzParityFilterTests.cs`
- Test: `tests/NATS.Server.Tests/Monitoring/ConnzParityFieldTests.cs`
- Test: `tests/NATS.Server.Tests/Monitoring/VarzSlowConsumerBreakdownTests.cs`
**Step 1: Write the failing test**
```csharp
[Fact]
public async Task Connz_filters_by_user_account_and_subject_and_includes_tls_peer_and_jwt_metadata()
{
await using var fx = await MonitoringParityFixture.StartAsync();
var connz = await fx.GetConnzAsync("?user=u&acc=A&filter_subject=orders.*&subs=detail");
connz.Conns.ShouldAllBe(c => c.Account == "A");
}
```
**Step 2: Run test to verify it fails**
Run: `dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~ConnzParityFilterTests|FullyQualifiedName~ConnzParityFieldTests|FullyQualifiedName~VarzSlowConsumerBreakdownTests" -v minimal`
Expected: FAIL because filters/fields are not fully populated.
**Step 3: Write minimal implementation**
```csharp
if (!string.IsNullOrEmpty(opts.User)) conns = conns.Where(c => c.AuthorizedUser == opts.User).ToList();
if (!string.IsNullOrEmpty(opts.Account)) conns = conns.Where(c => c.Account == opts.Account).ToList();
if (!string.IsNullOrEmpty(opts.FilterSubject)) conns = conns.Where(c => c.Subs.Any(s => SubjectMatch.MatchLiteral(s, opts.FilterSubject))).ToList();
```
```csharp
info.TlsPeerCertSubject = client.TlsState?.PeerSubject ?? "";
info.JwtIssuerKey = client.AuthContext?.IssuerKey ?? "";
```
**Step 4: Run test to verify it passes**
Run: `dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~ConnzParityFilterTests|FullyQualifiedName~ConnzParityFieldTests|FullyQualifiedName~VarzSlowConsumerBreakdownTests" -v minimal`
Expected: PASS.
**Step 5: Commit**
```bash
git add src/NATS.Server/Monitoring/ConnzHandler.cs src/NATS.Server/Monitoring/Connz.cs src/NATS.Server/Monitoring/VarzHandler.cs src/NATS.Server/Monitoring/Varz.cs src/NATS.Server/Monitoring/ClosedClient.cs tests/NATS.Server.Tests/Monitoring/ConnzParityFilterTests.cs tests/NATS.Server.Tests/Monitoring/ConnzParityFieldTests.cs tests/NATS.Server.Tests/Monitoring/VarzSlowConsumerBreakdownTests.cs
git commit -m "feat: close monitoring parity filters and field coverage"
```
### Task 12: Complete JetStream Stream Runtime Feature Parity
**Files:**
- Modify: `src/NATS.Server/JetStream/Models/StreamConfig.cs`
- Modify: `src/NATS.Server/JetStream/StreamManager.cs`
- Modify: `src/NATS.Server/JetStream/Publish/JetStreamPublisher.cs`
- Modify: `src/NATS.Server/JetStream/Publish/PublishPreconditions.cs`
- Modify: `src/NATS.Server/JetStream/Api/Handlers/StreamApiHandlers.cs`
- Modify: `src/NATS.Server/JetStream/Validation/JetStreamConfigValidator.cs`
- Test: `tests/NATS.Server.Tests/JetStream/JetStreamStreamRuntimeParityTests.cs`
- Test: `tests/NATS.Server.Tests/JetStream/JetStreamStreamFeatureToggleParityTests.cs`
**Step 1: Write the failing test**
```csharp
[Fact]
public async Task Stream_runtime_enforces_retention_ttl_per_subject_max_msg_size_and_guard_flags_with_go_error_contracts()
{
await using var fx = await JetStreamRuntimeFixture.StartWithStrictPolicyAsync();
var ack = await fx.PublishAsync("orders.created", payloadSize: 2048);
ack.ErrorCode.ShouldBe(10054);
}
```
**Step 2: Run test to verify it fails**
Run: `dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~JetStreamStreamRuntimeParityTests|FullyQualifiedName~JetStreamStreamFeatureToggleParityTests" -v minimal`
Expected: FAIL due incomplete runtime semantics for remaining stream rows.
**Step 3: Write minimal implementation**
```csharp
ApplyRetentionPolicy(stream, nowUtc); // Limits / Interest / WorkQueue behavior
ApplyPerSubjectCaps(stream);
if (config.Sealed || (isDelete && config.DenyDelete) || (isPurge && config.DenyPurge)) return Error(10052);
```
**Step 4: Run test to verify it passes**
Run: `dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~JetStreamStreamRuntimeParityTests|FullyQualifiedName~JetStreamStreamFeatureToggleParityTests" -v minimal`
Expected: PASS.
**Step 5: Commit**
```bash
git add src/NATS.Server/JetStream/Models/StreamConfig.cs src/NATS.Server/JetStream/StreamManager.cs src/NATS.Server/JetStream/Publish/JetStreamPublisher.cs src/NATS.Server/JetStream/Publish/PublishPreconditions.cs src/NATS.Server/JetStream/Api/Handlers/StreamApiHandlers.cs src/NATS.Server/JetStream/Validation/JetStreamConfigValidator.cs tests/NATS.Server.Tests/JetStream/JetStreamStreamRuntimeParityTests.cs tests/NATS.Server.Tests/JetStream/JetStreamStreamFeatureToggleParityTests.cs
git commit -m "feat: complete jetstream stream runtime parity"
```
### Task 13: Complete JetStream Consumer Runtime Parity
**Files:**
- Modify: `src/NATS.Server/JetStream/Models/ConsumerConfig.cs`
- Modify: `src/NATS.Server/JetStream/ConsumerManager.cs`
- 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/Api/Handlers/ConsumerApiHandlers.cs`
- Test: `tests/NATS.Server.Tests/JetStream/JetStreamConsumerRuntimeParityTests.cs`
- Test: `tests/NATS.Server.Tests/JetStream/JetStreamConsumerFlowReplayParityTests.cs`
**Step 1: Write the failing test**
```csharp
[Fact]
public async Task Consumer_runtime_honors_deliver_policy_ack_all_redelivery_max_deliver_backoff_flow_rate_and_replay_timing()
{
await using var fx = await JetStreamConsumerRuntimeFixture.StartAsync();
var result = await fx.RunScenarioAsync();
result.UnexpectedTransitions.ShouldBeEmpty();
}
```
**Step 2: Run test to verify it fails**
Run: `dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~JetStreamConsumerRuntimeParityTests|FullyQualifiedName~JetStreamConsumerFlowReplayParityTests" -v minimal`
Expected: FAIL while baseline behavior remains.
**Step 3: Write minimal implementation**
```csharp
if (ackPolicy == AckPolicy.All) _ackState.AdvanceFloor(seq);
if (deliveries >= config.MaxDeliver) return DeliveryDecision.Drop;
if (config.FlowControl) enqueue(FlowControlFrame());
```
**Step 4: Run test to verify it passes**
Run: `dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~JetStreamConsumerRuntimeParityTests|FullyQualifiedName~JetStreamConsumerFlowReplayParityTests" -v minimal`
Expected: PASS.
**Step 5: Commit**
```bash
git add src/NATS.Server/JetStream/Models/ConsumerConfig.cs src/NATS.Server/JetStream/ConsumerManager.cs 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/Api/Handlers/ConsumerApiHandlers.cs tests/NATS.Server.Tests/JetStream/JetStreamConsumerRuntimeParityTests.cs tests/NATS.Server.Tests/JetStream/JetStreamConsumerFlowReplayParityTests.cs
git commit -m "feat: complete jetstream consumer runtime parity"
```
### Task 14: Complete JetStream Storage Backend Parity (Layout, Indexing, TTL, Compression, Encryption)
**Files:**
- Modify: `src/NATS.Server/JetStream/Storage/IStreamStore.cs`
- Modify: `src/NATS.Server/JetStream/Storage/FileStoreOptions.cs`
- Modify: `src/NATS.Server/JetStream/Storage/FileStoreBlock.cs`
- Modify: `src/NATS.Server/JetStream/Storage/FileStore.cs`
- Modify: `src/NATS.Server/JetStream/Storage/MemStore.cs`
- Test: `tests/NATS.Server.Tests/JetStream/JetStreamFileStoreLayoutParityTests.cs`
- Test: `tests/NATS.Server.Tests/JetStream/JetStreamFileStoreCryptoCompressionTests.cs`
**Step 1: Write the failing test**
```csharp
[Fact]
public async Task File_store_uses_block_index_layout_with_ttl_prune_and_optional_compression_encryption_roundtrip()
{
await using var fx = await FileStoreParityFixture.StartAsync();
await fx.AppendManyAsync(10000);
(await fx.ValidateBlockAndIndexInvariantsAsync()).ShouldBeTrue();
}
```
**Step 2: Run test to verify it fails**
Run: `dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~JetStreamFileStoreLayoutParityTests|FullyQualifiedName~JetStreamFileStoreCryptoCompressionTests" -v minimal`
Expected: FAIL because storage semantics are still simplified.
**Step 3: Write minimal implementation**
```csharp
public sealed record SequencePointer(int BlockId, int Slot, long Offset);
if (_options.EnableCompression) bytes = S2Codec.Compress(bytes);
if (_options.EnableEncryption) bytes = _crypto.Encrypt(bytes, nonce);
```
**Step 4: Run test to verify it passes**
Run: `dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~JetStreamFileStoreLayoutParityTests|FullyQualifiedName~JetStreamFileStoreCryptoCompressionTests" -v minimal`
Expected: PASS.
**Step 5: Commit**
```bash
git add src/NATS.Server/JetStream/Storage/IStreamStore.cs src/NATS.Server/JetStream/Storage/FileStoreOptions.cs src/NATS.Server/JetStream/Storage/FileStoreBlock.cs src/NATS.Server/JetStream/Storage/FileStore.cs src/NATS.Server/JetStream/Storage/MemStore.cs tests/NATS.Server.Tests/JetStream/JetStreamFileStoreLayoutParityTests.cs tests/NATS.Server.Tests/JetStream/JetStreamFileStoreCryptoCompressionTests.cs
git commit -m "feat: complete jetstream storage backend parity"
```
### Task 15: Complete Mirror/Source Parity (Mirror Consumer, Source Mapping, Cross-Account)
**Files:**
- Modify: `src/NATS.Server/JetStream/MirrorSource/MirrorCoordinator.cs`
- Modify: `src/NATS.Server/JetStream/MirrorSource/SourceCoordinator.cs`
- Modify: `src/NATS.Server/JetStream/StreamManager.cs`
- Modify: `src/NATS.Server/Auth/Account.cs`
- Test: `tests/NATS.Server.Tests/JetStream/JetStreamMirrorSourceRuntimeParityTests.cs`
**Step 1: Write the failing test**
```csharp
[Fact]
public async Task Mirror_source_runtime_enforces_cross_account_permissions_and_subject_mapping_with_sync_state_tracking()
{
await using var fx = await MirrorSourceParityFixture.StartAsync();
var sync = await fx.GetSyncStateAsync("AGG");
sync.LastOriginSequence.ShouldBeGreaterThan(0);
}
```
**Step 2: Run test to verify it fails**
Run: `dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~JetStreamMirrorSourceRuntimeParityTests" -v minimal`
Expected: FAIL due missing runtime parity semantics.
**Step 3: Write minimal implementation**
```csharp
if (!_accountPolicy.CanMirror(sourceAccount, targetAccount)) return;
subject = _sourceTransform.Apply(subject);
_mirrorState.Update(originSequence, DateTime.UtcNow);
```
**Step 4: Run test to verify it passes**
Run: `dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~JetStreamMirrorSourceRuntimeParityTests" -v minimal`
Expected: PASS.
**Step 5: Commit**
```bash
git add src/NATS.Server/JetStream/MirrorSource/MirrorCoordinator.cs src/NATS.Server/JetStream/MirrorSource/SourceCoordinator.cs src/NATS.Server/JetStream/StreamManager.cs src/NATS.Server/Auth/Account.cs tests/NATS.Server.Tests/JetStream/JetStreamMirrorSourceRuntimeParityTests.cs
git commit -m "feat: complete mirror and source runtime parity"
```
### Task 16: Complete RAFT Consensus Parity (Heartbeat, NextIndex, Snapshot Transfer, Membership)
**Files:**
- Modify: `src/NATS.Server/Raft/RaftRpcContracts.cs`
- Modify: `src/NATS.Server/Raft/RaftTransport.cs`
- Modify: `src/NATS.Server/Raft/RaftReplicator.cs`
- Modify: `src/NATS.Server/Raft/RaftNode.cs`
- Modify: `src/NATS.Server/Raft/RaftLog.cs`
- Modify: `src/NATS.Server/Raft/RaftSnapshotStore.cs`
- Test: `tests/NATS.Server.Tests/Raft/RaftConsensusRuntimeParityTests.cs`
- Test: `tests/NATS.Server.Tests/Raft/RaftSnapshotTransferRuntimeParityTests.cs`
- Test: `tests/NATS.Server.Tests/Raft/RaftMembershipRuntimeParityTests.cs`
**Step 1: Write the failing test**
```csharp
[Fact]
public async Task Raft_cluster_commits_with_next_index_backtracking_and_snapshot_install_for_lagging_follower()
{
await using var cluster = await RaftRuntimeFixture.StartThreeNodeAsync();
(await cluster.RunCommitAndCatchupScenarioAsync()).ShouldBeTrue();
}
```
**Step 2: Run test to verify it fails**
Run: `dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~RaftConsensusRuntimeParityTests|FullyQualifiedName~RaftSnapshotTransferRuntimeParityTests|FullyQualifiedName~RaftMembershipRuntimeParityTests" -v minimal`
Expected: FAIL under current hook-level behavior.
**Step 3: Write minimal implementation**
```csharp
while (!AppendEntriesAccepted(follower, nextIndex[follower])) nextIndex[follower]--;
if (nextIndex[follower] <= snapshot.LastIncludedIndex) await transport.InstallSnapshotAsync(...);
```
**Step 4: Run test to verify it passes**
Run: `dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~RaftConsensusRuntimeParityTests|FullyQualifiedName~RaftSnapshotTransferRuntimeParityTests|FullyQualifiedName~RaftMembershipRuntimeParityTests" -v minimal`
Expected: PASS.
**Step 5: Commit**
```bash
git add src/NATS.Server/Raft/RaftRpcContracts.cs src/NATS.Server/Raft/RaftTransport.cs src/NATS.Server/Raft/RaftReplicator.cs src/NATS.Server/Raft/RaftNode.cs src/NATS.Server/Raft/RaftLog.cs src/NATS.Server/Raft/RaftSnapshotStore.cs tests/NATS.Server.Tests/Raft/RaftConsensusRuntimeParityTests.cs tests/NATS.Server.Tests/Raft/RaftSnapshotTransferRuntimeParityTests.cs tests/NATS.Server.Tests/Raft/RaftMembershipRuntimeParityTests.cs
git commit -m "feat: complete raft runtime consensus parity"
```
### Task 17: Complete JetStream Cluster Governance and Cross-Cluster JetStream Parity
**Files:**
- Modify: `src/NATS.Server/JetStream/Cluster/JetStreamMetaGroup.cs`
- Modify: `src/NATS.Server/JetStream/Cluster/StreamReplicaGroup.cs`
- Modify: `src/NATS.Server/JetStream/Cluster/AssetPlacementPlanner.cs`
- Modify: `src/NATS.Server/NatsServer.cs`
- Modify: `src/NATS.Server/Gateways/GatewayManager.cs`
- Test: `tests/NATS.Server.Tests/JetStream/JetStreamClusterGovernanceRuntimeParityTests.cs`
- Test: `tests/NATS.Server.Tests/JetStream/JetStreamCrossClusterRuntimeParityTests.cs`
**Step 1: Write the failing test**
```csharp
[Fact]
public async Task Jetstream_cluster_governance_applies_consensus_backed_placement_and_cross_cluster_replication()
{
await using var fx = await JetStreamClusterRuntimeFixture.StartAsync();
var result = await fx.CreateAndReplicateStreamAsync();
result.Success.ShouldBeTrue();
}
```
**Step 2: Run test to verify it fails**
Run: `dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~JetStreamClusterGovernanceRuntimeParityTests|FullyQualifiedName~JetStreamCrossClusterRuntimeParityTests" -v minimal`
Expected: FAIL while governance and cross-cluster paths are still partial.
**Step 3: Write minimal implementation**
```csharp
await _metaGroup.ProposePlacementAsync(stream, replicas, ct);
await _replicaGroup.ApplyCommittedPlacementAsync(plan, ct);
if (message.Subject.StartsWith("$JS.CLUSTER.")) await _gatewayManager.ForwardJetStreamClusterMessageAsync(message, ct);
```
**Step 4: Run test to verify it passes**
Run: `dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~JetStreamClusterGovernanceRuntimeParityTests|FullyQualifiedName~JetStreamCrossClusterRuntimeParityTests" -v minimal`
Expected: PASS.
**Step 5: Commit**
```bash
git add src/NATS.Server/JetStream/Cluster/JetStreamMetaGroup.cs src/NATS.Server/JetStream/Cluster/StreamReplicaGroup.cs src/NATS.Server/JetStream/Cluster/AssetPlacementPlanner.cs src/NATS.Server/NatsServer.cs src/NATS.Server/Gateways/GatewayManager.cs tests/NATS.Server.Tests/JetStream/JetStreamClusterGovernanceRuntimeParityTests.cs tests/NATS.Server.Tests/JetStream/JetStreamCrossClusterRuntimeParityTests.cs
git commit -m "feat: complete jetstream cluster governance and cross-cluster parity"
```
### Task 18: Implement MQTT Transport Parity Baseline-to-Feature Completion
**Files:**
- Modify: `src/NATS.Server/NatsServer.cs`
- Create: `src/NATS.Server/Mqtt/MqttListener.cs`
- Create: `src/NATS.Server/Mqtt/MqttConnection.cs`
- Create: `src/NATS.Server/Mqtt/MqttProtocolParser.cs`
- Modify: `src/NATS.Server/Configuration/MqttOptions.cs`
- Test: `tests/NATS.Server.Tests/Mqtt/MqttListenerParityTests.cs`
- Test: `tests/NATS.Server.Tests/Mqtt/MqttPublishSubscribeParityTests.cs`
**Step 1: Write the failing test**
```csharp
[Fact]
public async Task Mqtt_listener_accepts_connect_and_routes_publish_to_matching_subscription()
{
await using var fx = await MqttFixture.StartAsync();
var payload = await fx.PublishAndReceiveAsync("sensors.temp", "42");
payload.ShouldBe("42");
}
```
**Step 2: Run test to verify it fails**
Run: `dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~MqttListenerParityTests|FullyQualifiedName~MqttPublishSubscribeParityTests" -v minimal`
Expected: FAIL because MQTT transport listener is not implemented.
**Step 3: Write minimal implementation**
```csharp
_listener = new TcpListener(IPAddress.Parse(_opts.Host), _opts.Port);
while (!ct.IsCancellationRequested) _ = HandleAsync(await _listener.AcceptTcpClientAsync(ct), ct);
```
```csharp
if (packet.Type == MqttPacketType.Publish) _router.ProcessMessage(topic, null, default, payload, mqttClientAdapter);
```
**Step 4: Run test to verify it passes**
Run: `dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~MqttListenerParityTests|FullyQualifiedName~MqttPublishSubscribeParityTests" -v minimal`
Expected: PASS.
**Step 5: Commit**
```bash
git add src/NATS.Server/NatsServer.cs src/NATS.Server/Mqtt/MqttListener.cs src/NATS.Server/Mqtt/MqttConnection.cs src/NATS.Server/Mqtt/MqttProtocolParser.cs src/NATS.Server/Configuration/MqttOptions.cs tests/NATS.Server.Tests/Mqtt/MqttListenerParityTests.cs tests/NATS.Server.Tests/Mqtt/MqttPublishSubscribeParityTests.cs
git commit -m "feat: add mqtt transport parity implementation"
```
### Task 19: Final Docs and Verification Closure
**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`
**Step 1: Write the failing test**
```csharp
[Fact]
public void Differences_table_has_no_remaining_unresolved_rows_after_full_parity_execution()
{
var report = ParityRowInspector.Load("differences.md");
report.UnresolvedRows.ShouldBeEmpty();
}
```
**Step 2: Run test to verify it fails**
Run: `dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~DifferencesParityClosureTests" -v minimal`
Expected: FAIL until all rows are updated from validated evidence.
**Step 3: Write minimal implementation**
```markdown
## Summary: Remaining Gaps
### Full Repo
None in tracked scope after this plan; unresolved table rows are closed or explicitly blocked with evidence.
```
**Step 4: Run verification gates**
Run: `dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~JetStream|FullyQualifiedName~Raft|FullyQualifiedName~Route|FullyQualifiedName~Gateway|FullyQualifiedName~Leaf|FullyQualifiedName~SubList|FullyQualifiedName~Connz|FullyQualifiedName~Varz|FullyQualifiedName~Auth|FullyQualifiedName~Mqtt|FullyQualifiedName~DifferencesParityClosureTests" -v minimal`
Expected: PASS.
Run: `dotnet test -v minimal`
Expected: PASS.
**Step 5: Commit**
```bash
git add differences.md docs/plans/2026-02-23-jetstream-remaining-parity-map.md docs/plans/2026-02-23-jetstream-remaining-parity-verification.md
git commit -m "docs: close full-repo parity gaps with verified evidence"
```