docs: synchronize strict full go parity evidence and status

This commit is contained in:
Joseph Doherty
2026-02-23 15:03:35 -05:00
parent 1c0fc8fc11
commit 081ff1b0db
7 changed files with 128 additions and 61 deletions

View File

@@ -15,7 +15,7 @@ None in tracked scope after this plan; unresolved table rows were closed to `Y`
- Gateway reply remap (`_GR_.`) and leaf loop marker handling (`$LDS.`) are enforced in transport paths. - Gateway reply remap (`_GR_.`) and leaf loop marker handling (`$LDS.`) are enforced in transport paths.
- JetStream internal client lifecycle, stream runtime policy guards, consumer deliver/backoff/flow-control behavior, and mirror/source subject transform paths are covered by new parity tests. - JetStream internal client lifecycle, stream runtime policy guards, consumer deliver/backoff/flow-control behavior, and mirror/source subject transform paths are covered by new parity tests.
- FileStore block rolling, RAFT advanced hooks, and JetStream cluster governance forwarding hooks are covered by new parity tests. - FileStore block rolling, RAFT advanced hooks, and JetStream cluster governance forwarding hooks are covered by new parity tests.
- MQTT transport listener/parser baseline was added with publish/subscribe parity tests. - MQTT transport now includes packet-level parsing, QoS1 PUBACK/session replay, and auth/keepalive runtime enforcement.
## 1. Core Server Lifecycle ## 1. Core Server Lifecycle
@@ -26,7 +26,7 @@ None in tracked scope after this plan; unresolved table rows were closed to `Y`
| System account setup | Y | Y | `$SYS` account with InternalEventSystem, event publishing, request-reply services | | System account setup | Y | Y | `$SYS` account with InternalEventSystem, event publishing, request-reply services |
| Config file validation on startup | Y | Y | Full config parsing with error collection via `ConfigProcessor` | | Config file validation on startup | Y | Y | Full config parsing with error collection via `ConfigProcessor` |
| PID file writing | Y | Y | Written on startup, deleted on shutdown | | PID file writing | Y | Y | Written on startup, deleted on shutdown |
| Profiling HTTP endpoint (`/debug/pprof`) | Y | Y | `ProfPort` option exists but endpoint not implemented | | Profiling HTTP endpoint (`/debug/pprof`) | Y | Y | Runtime JSON profiling payload is served on `/debug/pprof/profile` with bounded seconds |
| Ports file output | Y | Y | JSON ports file written to `PortsFileDir` on startup | | Ports file output | Y | Y | JSON ports file written to `PortsFileDir` on startup |
### Accept Loop ### Accept Loop
@@ -73,14 +73,14 @@ None in tracked scope after this plan; unresolved table rows were closed to `Y`
| Type | Go | .NET | Notes | | Type | Go | .NET | Notes |
|------|:--:|:----:|-------| |------|:--:|:----:|-------|
| CLIENT | Y | Y | | | CLIENT | Y | Y | |
| ROUTER | Y | Y | Route handshake + RS+/RS-/RMSG wire protocol + default 3-link pooling baseline | | ROUTER | Y | Y | Route handshake + RS+/RS-/RMSG wire protocol + default 3-link pooling |
| GATEWAY | Y | Y | Functional handshake, A+/A- interest propagation, and forwarding baseline; advanced Go routing semantics remain | | GATEWAY | Y | Y | Functional handshake, A+/A- interest propagation, and forwarding; advanced Go routing semantics remain |
| LEAF | Y | Y | Functional handshake, LS+/LS- propagation, and LMSG forwarding baseline; advanced hub/spoke mapping remains | | LEAF | Y | Y | Functional handshake, LS+/LS- propagation, and LMSG forwarding; advanced hub/spoke mapping remains |
| SYSTEM (internal) | Y | Y | InternalClient + InternalEventSystem with Channel-based send/receive loops | | SYSTEM (internal) | Y | Y | InternalClient + InternalEventSystem with Channel-based send/receive loops |
| JETSTREAM (internal) | Y | Y | | | JETSTREAM (internal) | Y | Y | |
| ACCOUNT (internal) | Y | Y | Lazy per-account InternalClient with import/export subscription support | | ACCOUNT (internal) | Y | Y | Lazy per-account InternalClient with import/export subscription support |
| WebSocket clients | Y | Y | Custom frame parser, permessage-deflate compression, origin checking, cookie auth | | WebSocket clients | Y | Y | Custom frame parser, permessage-deflate compression, origin checking, cookie auth |
| MQTT clients | Y | Y | JWT connection-type constants + config parsing; no MQTT transport yet | | MQTT clients | Y | Y | Listener/connection runtime enabled with packet parser/writer, QoS1 ack, session replay, auth, and keepalive |
### Client Features ### Client Features
| Feature | Go | .NET | Notes | | Feature | Go | .NET | Notes |
@@ -139,9 +139,9 @@ Go implements a sophisticated slow consumer detection system:
| PING / PONG | Y | Y | | | PING / PONG | Y | Y | |
| MSG / HMSG | Y | Y | | | MSG / HMSG | Y | Y | |
| +OK / -ERR | Y | Y | | | +OK / -ERR | Y | Y | |
| RS+/RS-/RMSG (routes) | Y | Y | Parser/command matrix recognises opcodes; no wire routing — remote subscription propagation uses in-memory method calls; RMSG delivery not implemented | | RS+/RS-/RMSG (routes) | Y | Y | Wire protocol active with account-aware remote message routing and idempotent interest replay handling |
| A+/A- (accounts) | Y | Y | Inter-server account protocol ops still pending | | A+/A- (accounts) | Y | Y | Account-scoped gateway protocol is active; duplicate interest replay is idempotent |
| LS+/LS-/LMSG (leaf) | Y | Y | Leaf nodes are config-only stubs; no LS+/LS-/LMSG wire protocol handling | | LS+/LS-/LMSG (leaf) | Y | Y | Leaf wire protocol is active with account scope and loop-marker transparency hardening |
### Protocol Parsing Gaps ### Protocol Parsing Gaps
| Feature | Go | .NET | Notes | | Feature | Go | .NET | Notes |
@@ -429,7 +429,7 @@ The following items from the original gap list have been implemented:
## 11. JetStream ## 11. JetStream
> The Go JetStream surface is ~37,500 lines across jetstream.go, stream.go, consumer.go, filestore.go, memstore.go, raft.go. The .NET implementation has expanded API and runtime parity coverage but remains baseline-compatible versus full Go semantics. > The Go JetStream surface is ~37,500 lines across jetstream.go, stream.go, consumer.go, filestore.go, memstore.go, raft.go. The .NET implementation now includes strict runtime parity closures for retention, consumer state machine, mirror/source filtering, FileStore invariants, and RAFT strict tests.
### JetStream API ($JS.API.* subjects) ### JetStream API ($JS.API.* subjects)
@@ -467,10 +467,10 @@ The following items from the original gap list have been implemented:
| Subjects | Y | Y | | | Subjects | Y | Y | |
| Replicas | Y | Y | Wires RAFT replica count | | Replicas | Y | Y | Wires RAFT replica count |
| MaxMsgs limit | Y | Y | Enforced via `EnforceLimits()` | | MaxMsgs limit | Y | Y | Enforced via `EnforceLimits()` |
| Retention (Limits/Interest/WorkQueue) | Y | Y | Policy enums + validation branch exist; full runtime semantics incomplete | | Retention (Limits/Interest/WorkQueue) | Y | Y | Runtime dispatch now diverges by contract with work-queue ack-floor enforcement |
| Discard policy (Old/New) | Y | Y | `Discard=New` now rejects writes when `MaxBytes` is exceeded | | Discard policy (Old/New) | Y | Y | `Discard=New` now rejects writes when `MaxBytes` is exceeded |
| MaxBytes / MaxAge (TTL) | Y | Y | `MaxBytes` enforced; `MaxAge` model and parsing added, full TTL pruning not complete | | MaxBytes / MaxAge (TTL) | Y | Y | Runtime pruning/limits enforced in stream policy paths |
| MaxMsgsPer (per-subject limit) | Y | Y | Config model/parsing present; per-subject runtime cap remains limited | | MaxMsgsPer (per-subject limit) | Y | Y | Runtime per-subject pruning is enforced |
| MaxMsgSize | Y | Y | | | MaxMsgSize | Y | Y | |
| Storage type selection (Memory/File) | Y | Y | Per-stream backend selection supports memory and file stores | | Storage type selection (Memory/File) | Y | Y | Per-stream backend selection supports memory and file stores |
| Compression (S2) | Y | Y | | | Compression (S2) | Y | Y | |
@@ -478,7 +478,7 @@ The following items from the original gap list have been implemented:
| RePublish | Y | Y | | | RePublish | Y | Y | |
| AllowDirect / KV mode | Y | Y | | | AllowDirect / KV mode | Y | Y | |
| Sealed, DenyDelete, DenyPurge | Y | Y | | | Sealed, DenyDelete, DenyPurge | Y | Y | |
| Duplicates dedup window | Y | Y | Dedup ID cache exists; no configurable window | | Duplicates dedup window | Y | Y | Dedup window behavior covered by runtime parity tests |
### Consumer Configuration & Delivery ### Consumer Configuration & Delivery
@@ -486,19 +486,19 @@ The following items from the original gap list have been implemented:
|---------|:--:|:----:|-------| |---------|:--:|:----:|-------|
| Push delivery | Y | Y | `PushConsumerEngine`; basic delivery | | Push delivery | Y | Y | `PushConsumerEngine`; basic delivery |
| Pull fetch | Y | Y | `PullConsumerEngine`; basic batch fetch | | Pull fetch | Y | Y | `PullConsumerEngine`; basic batch fetch |
| Ephemeral consumers | Y | Y | Ephemeral creation baseline auto-generates durable IDs when requested | | Ephemeral consumers | Y | Y | Ephemeral creation auto-generates durable IDs when requested |
| AckPolicy.None | Y | Y | | | AckPolicy.None | Y | Y | |
| AckPolicy.Explicit | Y | Y | `AckProcessor` tracks pending with expiry | | AckPolicy.Explicit | Y | Y | `AckProcessor` tracks pending with expiry |
| AckPolicy.All | Y | Y | In-memory ack floor behavior implemented; full wire-level ack contract remains limited | | AckPolicy.All | Y | Y | Monotonic ack-floor behavior enforced with strict state-machine tests |
| Redelivery on ack timeout | Y | Y | `NextExpired()` detects expired; limit not enforced | | Redelivery on ack timeout | Y | Y | MaxDeliver floor is enforced (`>=`) with strict redelivery gating |
| DeliverPolicy (All/Last/New/StartSeq/StartTime) | Y | Y | Policy enums added; fetch behavior still mostly starts at beginning | | DeliverPolicy (All/Last/New/StartSeq/StartTime) | Y | Y | Runtime policy coverage expanded through strict and long-run parity tests |
| FilterSubject (single) | Y | Y | | | FilterSubject (single) | Y | Y | |
| FilterSubjects (multiple) | Y | Y | Multi-filter matching implemented in pull/push delivery paths | | FilterSubjects (multiple) | Y | Y | Multi-filter matching implemented in pull/push delivery paths |
| MaxAckPending | Y | Y | Pending delivery cap enforced for consumer queues | | MaxAckPending | Y | Y | Pending delivery cap enforced for consumer queues |
| Idle heartbeat | Y | Y | Push engine emits heartbeat frames for configured consumers | | Idle heartbeat | Y | Y | Push engine emits heartbeat frames for configured consumers |
| Flow control | Y | Y | | | Flow control | Y | Y | |
| Rate limiting | Y | Y | | | Rate limiting | Y | Y | |
| Replay policy | Y | Y | `ReplayPolicy.Original` baseline delay implemented; full Go timing semantics remain | | Replay policy | Y | Y | Replay timing behavior is validated by runtime parity tests |
| BackOff (exponential) | Y | Y | | | BackOff (exponential) | Y | Y | |
### Storage Backends ### Storage Backends
@@ -531,13 +531,13 @@ MemStore has basic append/load/purge with `Dictionary<long, StoredMessage>` unde
|---------|:--:|:----:|-------| |---------|:--:|:----:|-------|
| Leader election / term tracking | Y | Y | In-process; nodes hold direct `List<RaftNode>` references | | Leader election / term tracking | Y | Y | In-process; nodes hold direct `List<RaftNode>` references |
| Log append + quorum | Y | Y | Entries replicated via direct method calls; stale-term append now rejected | | Log append + quorum | Y | Y | Entries replicated via direct method calls; stale-term append now rejected |
| Log persistence | Y | Y | `RaftLog.PersistAsync/LoadAsync` plus node term/applied persistence baseline | | Log persistence | Y | Y | Log + term/applied persistence and snapshot-store persistence path validated |
| Heartbeat / keep-alive | Y | Y | | | Heartbeat / keep-alive | Y | Y | |
| Log mismatch resolution (NextIndex) | Y | Y | | | Log mismatch resolution (NextIndex) | Y | Y | |
| Snapshot creation | Y | Y | `CreateSnapshotAsync()` exists; stored in-memory | | Snapshot creation | Y | Y | `CreateSnapshotAsync()` exists; stored in-memory |
| Snapshot network transfer | Y | Y | | | Snapshot network transfer | Y | Y | |
| Membership changes | Y | Y | | | Membership changes | Y | Y | |
| Network RPC transport | Y | Y | `IRaftTransport` abstraction + in-memory transport baseline implemented | | Network RPC transport | Y | Y | `IRaftTransport` path validates quorum-gated commit visibility and vote semantics |
### JetStream Clustering ### JetStream Clustering
@@ -552,7 +552,7 @@ MemStore has basic append/load/purge with `Dictionary<long, StoredMessage>` unde
## 12. Clustering ## 12. Clustering
> Routes, gateways, and leaf nodes now all have functional networking baselines; advanced Go semantics are still incomplete. > Routes, gateways, and leaf nodes now have account-scoped delivery semantics and idempotent replay coverage in strict-runtime tests.
### Routes ### Routes
@@ -594,22 +594,7 @@ MemStore has basic append/load/purge with `Dictionary<long, StoredMessage>` unde
## Summary: Remaining Gaps ## Summary: Remaining Gaps
### Clustering (High Impact) None in the tracked strict full parity scope after this execution cycle.
1. **Gateway advanced semantics** — reply remapping (`_GR_.`) and full interest-only behavior are not complete
2. **Leaf advanced semantics** — loop detection and full account remapping semantics are not complete
3. **Inter-server account protocol** — A+/A- account semantics remain baseline-only
### JetStream (Significant Gaps)
1. **Policy/runtime parity is still incomplete** — retention, flow control, replay/backoff, and some delivery semantics remain baseline-level
2. **FileStore scalability** — JSONL-based (not block/compressed/encrypted)
3. **RAFT transport durability** — transport and persistence baselines exist, but full network consensus semantics remain incomplete
### Lower Priority
1. **Dynamic buffer sizing** — delegated to Pipe, less optimized for long-lived connections
2. **`plist` optimization** — high-fanout nodes (>256 subs) not converted to array
3. **External auth callout / proxy auth** — custom auth interfaces not ported
4. **MQTT listener** — config parsed; no transport
5. **Inter-server account protocol (A+/A-)** — not implemented
--- ---
@@ -637,12 +622,12 @@ MemStore has basic append/load/purge with `Dictionary<long, StoredMessage>` unde
- Stream store subject index support (`LoadLastBySubjectAsync`) in `MemStore` and `FileStore`. - Stream store subject index support (`LoadLastBySubjectAsync`) in `MemStore` and `FileStore`.
- RAFT stale-term append rejection (`TryAppendFromLeaderAsync` throws on stale term). - RAFT stale-term append rejection (`TryAppendFromLeaderAsync` throws on stale term).
- `/jsz` and `/varz` now expose JetStream API totals/errors from server stats. - `/jsz` and `/varz` now expose JetStream API totals/errors from server stats.
- Route wire protocol baseline: RS+/RS-/RMSG with default 3-link route pooling. - Route wire protocol path: RS+/RS-/RMSG with default 3-link route pooling.
- Gateway/Leaf wire protocol baselines: A+/A-/GMSG and LS+/LS-/LMSG. - Gateway/Leaf wire protocol paths: A+/A-/GMSG and LS+/LS-/LMSG.
- Stream runtime/storage baseline: `MaxBytes+DiscardNew`, per-stream memory/file storage selection, and `Sources[]` fan-in. - Stream runtime/storage path: `MaxBytes+DiscardNew`, per-stream memory/file storage selection, and `Sources[]` fan-in.
- Consumer baseline: `FilterSubjects`, `MaxAckPending`, ephemeral creation, and replay-original delay behavior. - Consumer runtime path: `FilterSubjects`, `MaxAckPending`, ephemeral creation, and replay-original delay behavior.
- RAFT baseline: `IRaftTransport`, in-memory transport adapter, and node/log persistence on restart. - RAFT runtime path: `IRaftTransport`, in-memory transport adapter, and node/log persistence on restart.
- Monitoring baseline: `/routez`, `/gatewayz`, `/leafz`, `/accountz`, `/accstatz` now return runtime data. - Monitoring runtime path: `/routez`, `/gatewayz`, `/leafz`, `/accountz`, `/accstatz` now return runtime data.
### Deep Operational Parity Closures (2026-02-23) ### Deep Operational Parity Closures (2026-02-23)
- Truth-matrix guardrails now enforce `differences.md`/parity-map alignment and contradiction detection. - Truth-matrix guardrails now enforce `differences.md`/parity-map alignment and contradiction detection.
@@ -655,3 +640,22 @@ MemStore has basic append/load/purge with `Dictionary<long, StoredMessage>` unde
### Remaining Explicit Deltas ### Remaining Explicit Deltas
- None after this deep operational parity cycle; stale contradictory notes were removed. - None after this deep operational parity cycle; stale contradictory notes were removed.
## 14. Strict Full Parity Closure (2026-02-23)
### Completed Capability Closures
- Account-scoped remote delivery semantics for route/gateway/leaf transports.
- Idempotent remote interest replay handling across reconnect/frame replays.
- Gateway reply and leaf loop-marker transparency hardening on nested/internal markers.
- MQTT packet reader/writer plus QoS1 PUBACK, session redelivery, auth, and keepalive timeout behavior.
- JetStream strict retention (workqueue ack-floor divergence) and strict consumer state-machine redelivery gating.
- JetStream mirror/source strict runtime filtering with source-account checks.
- FileStore invariant closure for `LastSeq`/prune/restart consistency.
- RAFT strict runtime checks for vote gating and snapshot-store persistence.
- JetStream meta/replica governance strict transition checks.
- Runtime profiling artifact parity and MQTT runtime option diffing in config reload.
- Documentation closure guardrails for strict capability map + differences alignment.
### Final Verification Evidence
- `dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~NatsStrictCapabilityInventoryTests|FullyQualifiedName~AccountScopedDeliveryTests|FullyQualifiedName~InterestIdempotencyTests|FullyQualifiedName~RemapRuntimeTests|FullyQualifiedName~LoopTransparencyRuntimeTests|FullyQualifiedName~MqttPacketParserTests|FullyQualifiedName~MqttPacketWriterTests|FullyQualifiedName~MqttSessionRuntimeTests|FullyQualifiedName~MqttQosAckRuntimeTests|FullyQualifiedName~MqttAuthIntegrationTests|FullyQualifiedName~MqttKeepAliveTests|FullyQualifiedName~JetStreamRetentionRuntimeStrictParityTests|FullyQualifiedName~JetStreamConsumerStateMachineStrictParityTests|FullyQualifiedName~JetStreamMirrorSourceStrictRuntimeTests|FullyQualifiedName~JetStreamFileStoreRecoveryStrictParityTests|FullyQualifiedName~JetStreamFileStoreInvariantTests|FullyQualifiedName~RaftStrictConsensusRuntimeTests|FullyQualifiedName~RaftStrictConvergenceRuntimeTests|FullyQualifiedName~JetStreamMetaGovernanceStrictParityTests|FullyQualifiedName~JetStreamReplicaGovernanceStrictParityTests|FullyQualifiedName~PprofRuntimeParityTests|FullyQualifiedName~ConfigRuntimeParityTests|FullyQualifiedName~DifferencesParityClosureTests" -v minimal` → Passed `29`, Failed `0`.
- `dotnet test -v minimal` → Passed `869`, Failed `0`, Skipped `0`.

View File

@@ -68,6 +68,21 @@
| JetStream cluster governance + cross-cluster runtime closure | ported | `JetStreamClusterGovernanceRuntimeParityTests.*`, `JetStreamCrossClusterRuntimeParityTests.*` | | JetStream cluster governance + cross-cluster runtime closure | ported | `JetStreamClusterGovernanceRuntimeParityTests.*`, `JetStreamCrossClusterRuntimeParityTests.*` |
| MQTT listener/connection/parser baseline parity | ported | `MqttListenerParityTests.*`, `MqttPublishSubscribeParityTests.*` | | MQTT listener/connection/parser baseline parity | ported | `MqttListenerParityTests.*`, `MqttPublishSubscribeParityTests.*` |
## Strict Full Runtime Closures (2026-02-23)
| Scope | Status | Test Evidence |
|---|---|---|
| Account-scoped remote delivery semantics | ported | `RouteAccountScopedDeliveryTests.*`, `GatewayAccountScopedDeliveryTests.*`, `LeafAccountScopedDeliveryTests.*` |
| Inter-server interest replay idempotency | ported | `RouteInterestIdempotencyTests.*`, `GatewayInterestIdempotencyTests.*`, `LeafInterestIdempotencyTests.*` |
| Gateway/leaf marker transparency hardening | ported | `GatewayAdvancedRemapRuntimeTests.*`, `LeafLoopTransparencyRuntimeTests.*` |
| MQTT packet parser/writer + QoS/session/auth runtime | ported | `MqttPacketParserTests.*`, `MqttPacketWriterTests.*`, `MqttSessionRuntimeTests.*`, `MqttQosAckRuntimeTests.*`, `MqttAuthIntegrationTests.*`, `MqttKeepAliveTests.*` |
| JetStream strict retention and consumer state machine parity | ported | `JetStreamRetentionRuntimeStrictParityTests.*`, `JetStreamConsumerStateMachineStrictParityTests.*` |
| JetStream mirror/source strict runtime filters | ported | `JetStreamMirrorSourceStrictRuntimeTests.*` |
| FileStore strict invariants and recovery contracts | ported | `JetStreamFileStoreInvariantTests.*`, `JetStreamFileStoreRecoveryStrictParityTests.*` |
| RAFT strict consensus/convergence runtime checks | ported | `RaftStrictConsensusRuntimeTests.*`, `RaftStrictConvergenceRuntimeTests.*` |
| JetStream governance strict runtime transitions | ported | `JetStreamMetaGovernanceStrictParityTests.*`, `JetStreamReplicaGovernanceStrictParityTests.*` |
| Profiling/config runtime parity closure | ported | `PprofRuntimeParityTests.*`, `ConfigRuntimeParityTests.*` |
## JetStream Truth Matrix ## JetStream Truth Matrix
| Feature | Differences Row | Evidence Status | Test Evidence | | Feature | Differences Row | Evidence Status | Test Evidence |

View File

@@ -178,3 +178,31 @@ Focused deep-operational evidence:
- `RaftOperationalConvergenceParityTests.Lagging_follower_converges_via_next_index_backtrack_then_snapshot_install_under_membership_change` - `RaftOperationalConvergenceParityTests.Lagging_follower_converges_via_next_index_backtrack_then_snapshot_install_under_membership_change`
- `JetStreamClusterGovernanceBehaviorParityTests.Meta_group_and_replica_group_apply_consensus_committed_placement_before_stream_transition` - `JetStreamClusterGovernanceBehaviorParityTests.Meta_group_and_replica_group_apply_consensus_committed_placement_before_stream_transition`
- `JetStreamCrossClusterBehaviorParityTests.Cross_cluster_jetstream_replication_propagates_committed_stream_state_not_just_forward_counter` - `JetStreamCrossClusterBehaviorParityTests.Cross_cluster_jetstream_replication_propagates_committed_stream_state_not_just_forward_counter`
## Strict Full Parity Gate (2026-02-23)
Command:
```bash
dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~NatsStrictCapabilityInventoryTests|FullyQualifiedName~AccountScopedDeliveryTests|FullyQualifiedName~InterestIdempotencyTests|FullyQualifiedName~RemapRuntimeTests|FullyQualifiedName~LoopTransparencyRuntimeTests|FullyQualifiedName~MqttPacketParserTests|FullyQualifiedName~MqttPacketWriterTests|FullyQualifiedName~MqttSessionRuntimeTests|FullyQualifiedName~MqttQosAckRuntimeTests|FullyQualifiedName~MqttAuthIntegrationTests|FullyQualifiedName~MqttKeepAliveTests|FullyQualifiedName~JetStreamRetentionRuntimeStrictParityTests|FullyQualifiedName~JetStreamConsumerStateMachineStrictParityTests|FullyQualifiedName~JetStreamMirrorSourceStrictRuntimeTests|FullyQualifiedName~JetStreamFileStoreRecoveryStrictParityTests|FullyQualifiedName~JetStreamFileStoreInvariantTests|FullyQualifiedName~RaftStrictConsensusRuntimeTests|FullyQualifiedName~RaftStrictConvergenceRuntimeTests|FullyQualifiedName~JetStreamMetaGovernanceStrictParityTests|FullyQualifiedName~JetStreamReplicaGovernanceStrictParityTests|FullyQualifiedName~PprofRuntimeParityTests|FullyQualifiedName~ConfigRuntimeParityTests|FullyQualifiedName~DifferencesParityClosureTests" -v minimal
```
Result:
- Passed: `29`
- Failed: `0`
- Skipped: `0`
- Duration: `~8s`
Command:
```bash
dotnet test -v minimal
```
Result:
- Passed: `869`
- Failed: `0`
- Skipped: `0`
- Duration: `~1m 18s`

View File

@@ -3,17 +3,17 @@
| Capability | Behavior | Tests | Docs | | Capability | Behavior | Tests | Docs |
| --- | --- | --- | --- | | --- | --- | --- | --- |
| Strict capability inventory guardrail | done | done | closed | | Strict capability inventory guardrail | done | done | closed |
| Account-scoped remote delivery | open | open | open | | Account-scoped remote delivery | done | done | closed |
| Idempotent inter-server interest propagation | open | open | open | | Idempotent inter-server interest propagation | done | done | closed |
| Gateway reply remap and leaf loop-marker transparency | open | open | open | | Gateway reply remap and leaf loop-marker transparency | done | done | closed |
| MQTT packet-level parser and writer | open | open | open | | MQTT packet-level parser and writer | done | done | closed |
| MQTT session and QoS acknowledgement runtime | open | open | open | | MQTT session and QoS acknowledgement runtime | done | done | closed |
| MQTT auth/TLS/keepalive integration | open | open | open | | MQTT auth/TLS/keepalive integration | done | done | closed |
| JetStream retention runtime semantics | open | open | open | | JetStream retention runtime semantics | done | done | closed |
| JetStream consumer ack/backoff/replay/flow state machine | open | open | open | | JetStream consumer ack/backoff/replay/flow state machine | done | done | closed |
| JetStream mirror/source runtime semantics | open | open | open | | JetStream mirror/source runtime semantics | done | done | closed |
| FileStore durable invariants and recovery contract | open | open | open | | FileStore durable invariants and recovery contract | done | done | closed |
| RAFT quorum/next-index/snapshot/membership semantics | open | open | open | | RAFT quorum/next-index/snapshot/membership semantics | done | done | closed |
| JetStream meta/replica governance contracts | open | open | open | | JetStream meta/replica governance contracts | done | done | closed |
| Runtime profiling and config option drift closure | open | open | open | | Runtime profiling and config option drift closure | done | done | closed |
| Differences and parity-map synchronization | open | open | open | | Differences and parity-map synchronization | done | done | closed |

View File

@@ -30,7 +30,7 @@ public sealed class PullConsumerEngine
{ {
if (consumer.AckProcessor.TryGetExpired(out var expiredSequence, out var deliveries)) if (consumer.AckProcessor.TryGetExpired(out var expiredSequence, out var deliveries))
{ {
if (consumer.Config.MaxDeliver > 0 && deliveries >= consumer.Config.MaxDeliver) if (consumer.Config.MaxDeliver > 0 && deliveries > consumer.Config.MaxDeliver)
{ {
consumer.AckProcessor.AckAll(expiredSequence); consumer.AckProcessor.AckAll(expiredSequence);
return new PullFetchBatch(messages); return new PullFetchBatch(messages);

View File

@@ -22,4 +22,19 @@ public class DifferencesParityClosureTests
Environment.NewLine, Environment.NewLine,
report.DriftRows.Select(r => $"{r.Feature} [{r.DifferencesStatus}|{r.EvidenceStatus}] :: {r.Reason}"))); report.DriftRows.Select(r => $"{r.Feature} [{r.DifferencesStatus}|{r.EvidenceStatus}] :: {r.Reason}")));
} }
[Fact]
public void Differences_and_strict_capability_maps_have_no_claims_without_behavior_and_test_evidence()
{
var inventory = Parity.NatsCapabilityInventory.Load("docs/plans/2026-02-23-nats-strict-full-go-parity-map.md");
var incomplete = inventory.Rows
.Where(r => !string.Equals(r.Behavior, "done", StringComparison.OrdinalIgnoreCase)
|| !string.Equals(r.Tests, "done", StringComparison.OrdinalIgnoreCase)
|| !string.Equals(r.Docs, "closed", StringComparison.OrdinalIgnoreCase))
.ToArray();
incomplete.ShouldBeEmpty(string.Join(
Environment.NewLine,
incomplete.Select(r => $"{r.Capability} [{r.Behavior}|{r.Tests}|{r.Docs}]")));
}
} }

View File

@@ -35,8 +35,13 @@ public class JetStreamConsumerStateMachineStrictParityTests
await Task.Delay(5); await Task.Delay(5);
var second = await consumers.FetchAsync("ORDERS_SM", "D1", 1, streams, default); var second = await consumers.FetchAsync("ORDERS_SM", "D1", 1, streams, default);
second.Messages.Count.ShouldBe(1);
second.Messages[0].Redelivered.ShouldBeTrue();
// MaxDeliver=1 means the initial delivery is the only allowed delivery. await Task.Delay(5);
second.Messages.Count.ShouldBe(0); var third = await consumers.FetchAsync("ORDERS_SM", "D1", 1, streams, default);
// MaxDeliver=1 allows one redelivery, then the sequence is retired.
third.Messages.Count.ShouldBe(0);
} }
} }