Files
natsdotnet/gaps/protocol.md
Joseph Doherty c30e67a69d Fix E2E test gaps and add comprehensive E2E + parity test suites
- Fix pull consumer fetch: send original stream subject in HMSG (not inbox)
  so NATS client distinguishes data messages from control messages
- Fix MaxAge expiry: add background timer in StreamManager for periodic pruning
- Fix JetStream wire format: Go-compatible anonymous objects with string enums,
  proper offset-based pagination for stream/consumer list APIs
- Add 42 E2E black-box tests (core messaging, auth, TLS, accounts, JetStream)
- Add ~1000 parity tests across all subsystems (gaps closure)
- Update gap inventory docs to reflect implementation status
2026-03-12 14:09:23 -04:00

27 KiB
Raw Permalink Blame History

Protocol — Gap Analysis

This file tracks what has and hasn't been ported from Go to .NET for the Protocol module. See stillmissing.md for the full LOC comparison across all modules.

LLM Instructions: How to Analyze This Category

Step 1: Read the Go Reference Files

Read each Go source file listed below. For every file:

  1. Extract all exported types (structs, interfaces, type aliases)
  2. Extract all exported methods on those types (receiver functions)
  3. Extract all exported standalone functions
  4. Note key constants, enums, and protocol states
  5. Note important unexported helpers that implement core logic (functions >20 lines)
  6. Pay attention to concurrency patterns (goroutines, mutexes, channels) — these map to different .NET patterns

Step 2: Read the .NET Implementation Files

Read all .cs files in the .NET directories listed below. For each Go symbol found in Step 1:

  1. Search for a matching type, method, or function in .NET
  2. If found, compare the behavior: does it handle the same edge cases? Same error paths?
  3. If partially implemented, note what's missing
  4. If not found, note it as MISSING

Step 3: Cross-Reference Tests

Compare Go test functions against .NET test methods:

  1. For each Go Test* function, check if a corresponding .NET [Fact] or [Theory] exists
  2. Note which test scenarios are covered and which are missing
  3. Check the parity DB (docs/test_parity.db) for existing mappings:
    sqlite3 docs/test_parity.db "SELECT go_test, dotnet_test, confidence FROM test_mappings tm JOIN go_tests gt ON tm.go_test_id=gt.rowid JOIN dotnet_tests dt ON tm.dotnet_test_id=dt.rowid WHERE gt.go_file LIKE '%PATTERN%'"
    

Step 4: Classify Each Item

Use these status values:

Status Meaning
PORTED Equivalent exists in .NET with matching behavior
PARTIAL .NET implementation exists but is incomplete (missing edge cases, error handling, or features)
MISSING No .NET equivalent found — needs to be ported
NOT_APPLICABLE Go-specific pattern that doesn't apply to .NET (build tags, platform-specific goroutine tricks, etc.)
DEFERRED Intentionally skipped for now (document why)

Step 5: Fill In the Gap Inventory

Add rows to the Gap Inventory table below. Group by Go source file. Include the Go file and line number so a porting LLM can jump directly to the reference implementation.

Key Porting Notes for Protocol

  • The parser is a byte-by-byte state machine. In .NET, use System.IO.Pipelines for zero-copy parsing with ReadOnlySequence<byte>.
  • Control line limit: 4096 bytes. Default max payload: 1MB.
  • Extended protocol: HPUB/HMSG (headers), RPUB/RMSG (routes) — check if these are implemented.
  • Fuzz tests in Go may map to [Theory] tests with randomized inputs in .NET.

Go Reference Files (Source)

  • golang/nats-server/server/parser.go — Protocol state machine (PUB, SUB, UNSUB, CONNECT, INFO, PING/PONG, HPUB/HMSG, RPUB/RMSG)
  • golang/nats-server/server/proto.go — Wire-level protocol writing (sendProto, sendInfo, etc.)
  • golang/nats-server/server/const.go — Protocol constants, limits (control line 4096, default max payload 1MB)

Go Reference Files (Tests)

  • golang/nats-server/server/parser_test.go
  • golang/nats-server/server/parser_fuzz_test.go
  • golang/nats-server/server/server_fuzz_test.go
  • golang/nats-server/server/subject_fuzz_test.go
  • golang/nats-server/server/split_test.go

.NET Implementation Files (Source)

  • src/NATS.Server/Protocol/NatsParser.cs — State machine
  • src/NATS.Server/Protocol/NatsProtocol.cs — Wire-level writing
  • src/NATS.Server/Protocol/NatsHeaderParser.cs
  • src/NATS.Server/Protocol/ClientCommandMatrix.cs
  • src/NATS.Server/Protocol/MessageTraceContext.cs
  • src/NATS.Server/Protocol/ProxyProtocol.cs

.NET Implementation Files (Tests)

  • tests/NATS.Server.Tests/Protocol/

Gap Inventory

golang/nats-server/server/parser.go

Go Symbol Go File:Line Status .NET Equivalent Notes
parserState (type) parser.go:24 PORTED src/NATS.Server/Protocol/NatsParser.cs Go uses an iota int type; .NET uses enum CommandType + internal awaiting-payload state
parseState (struct) parser.go:25 PARTIAL src/NATS.Server/Protocol/NatsParser.cs:37 .NET NatsParser carries equivalent per-command state via fields (_awaitingPayload, _expectedPayloadSize, etc.). Missing: argBuf/msgBuf split-buffer accumulation fields, scratch fixed-size buffer, header lazy-parse field. The .NET parser relies on System.IO.Pipelines buffering rather than explicit accumulator fields.
pubArg (struct) parser.go:37 PARTIAL src/NATS.Server/Protocol/NatsParser.cs:21 ParsedCommand covers subject, reply, size, hdr. Missing: origin, account, pacache, mapped, queues, szb, hdb, psi, trace, delivered — clustering/routing/JetStream fields not yet needed for core client protocol.
OP_STARTINFO_ARG (parser state constants) parser.go:57134 PARTIAL src/NATS.Server/Protocol/NatsParser.cs:104 All CLIENT-facing states implemented (PUB, HPUB, SUB, UNSUB, CONNECT, INFO, PING, PONG, +OK, -ERR). MISSING states: OP_A/ASUB_ARG/AUSUB_ARG (A+/A- for gateways), OP_R/OP_RS/OP_L/OP_LS (RMSG/LMSG/RS+/RS-/LS+/LS-), OP_M/MSG_ARG/HMSG_ARG (routing MSG/HMSG). See ClientCommandMatrix.cs for partial routing opcode routing.
client.parse() parser.go:136 PARTIAL src/NATS.Server/Protocol/NatsParser.cs:69 Core CLIENT-facing parse loop ported as NatsParser.TryParse() using ReadOnlySequence<byte> + SequenceReader. Missing: byte-by-byte incremental state transitions (Go uses byte-by-byte state machine; .NET scans for \r\n on each call), auth-set check before non-CONNECT op, MQTT dispatch (c.mqttParse), gateway in-CONNECT gating, ROUTER/GATEWAY/LEAF protocol dispatch (RMSG, LMSG, RS+, RS-, A+, A-).
protoSnippet() parser.go:1236 PORTED src/NATS.Server/Protocol/NatsParser.cs:206 Added Go-style quoted snippet helper (ProtoSnippet(start,max,buffer)) and default overload, with parity tests in tests/NATS.Server.Tests/Protocol/ProtocolParserSnippetGapParityTests.cs.
client.overMaxControlLineLimit() parser.go:1251 PARTIAL src/NATS.Server/Protocol/NatsParser.cs:83 .NET now emits structured max-control-line errors with snippet context (snip=...). Missing: kind-check (Go only enforces for CLIENT) and explicit connection-close side effect (closeConnection(MaxControlLineExceeded)) at parser layer.
client.clonePubArg() parser.go:1267 MISSING Split-buffer scenario: clones pubArg and re-processes when payload spans two reads. Not needed in .NET because System.IO.Pipelines handles buffering, but there is no explicit equivalent.
parseState.getHeader() parser.go:1297 PARTIAL src/NATS.Server/Protocol/NatsHeaderParser.cs:25 Go lazily parses http.Header from the raw message buffer. .NET has NatsHeaderParser.Parse() which parses NATS/1.0 headers. Missing: lazy evaluation on the parsed command (header is not cached on ParsedCommand).

golang/nats-server/server/proto.go

Note: This Go file (proto.go) implements a protobuf wire-format scanner/encoder (field tags, varints, length-delimited bytes) used internally for NATS's binary internal protocol (e.g. JetStream metadata encoding). It is unrelated to the NATS text protocol.

Go Symbol Go File:Line Status .NET Equivalent Notes
errProtoInsufficient proto.go:24 PORTED src/NATS.Server/Protocol/ProtoWire.cs:5 Added sentinel-equivalent error constant and ProtoWireException usage for insufficient varint/bytes payloads.
errProtoOverflow proto.go:25 PORTED src/NATS.Server/Protocol/ProtoWire.cs:6 Added overflow sentinel-equivalent error constant for invalid 10-byte varint tails.
errProtoInvalidFieldNumber proto.go:26 PORTED src/NATS.Server/Protocol/ProtoWire.cs:7 Added invalid field-number sentinel-equivalent error constant used by tag scanning.
protoScanField() proto.go:28 PORTED src/NATS.Server/Protocol/ProtoWire.cs:9 Added field scanner that composes tag + value scanning and returns total consumed size.
protoScanTag() proto.go:42 PORTED src/NATS.Server/Protocol/ProtoWire.cs:16 Added tag scanner with Go-equivalent field number validation (1..int32).
protoScanFieldValue() proto.go:61 PORTED src/NATS.Server/Protocol/ProtoWire.cs:26 Added wire-type scanner for varint/fixed32/fixed64/length-delimited forms.
protoScanVarint() proto.go:77 PORTED src/NATS.Server/Protocol/ProtoWire.cs:38 Added 10-byte max varint scanner with insufficient/overflow parity errors.
protoScanBytes() proto.go:179 PORTED src/NATS.Server/Protocol/ProtoWire.cs:65 Added length-delimited scanner that validates the declared size against remaining payload bytes.
protoEncodeVarint() proto.go:190 PORTED src/NATS.Server/Protocol/ProtoWire.cs:74 Added varint encoder and round-trip coverage in parity tests.

golang/nats-server/server/const.go

Go Symbol Go File:Line Status .NET Equivalent Notes
Command (type) const.go:23 NOT_APPLICABLE Go string type alias for signal commands (stop/quit/reload). Managed by OS signal handling; not applicable to .NET server lifecycle which uses CancellationToken.
CommandStop, CommandQuit, CommandReopen, CommandReload const.go:2734 NOT_APPLICABLE OS signal-based server control commands. .NET uses CancellationToken + IHostedService lifecycle.
gitCommit, serverVersion (build vars) const.go:39 NOT_APPLICABLE Go linker-injected build vars. Equivalent handled by .NET assembly info / AssemblyInformationalVersionAttribute.
formatRevision() const.go:47 NOT_APPLICABLE Formats a 7-char VCS commit hash for display. Go-specific build info pattern; not needed in .NET.
init() (build info) const.go:54 NOT_APPLICABLE Reads debug.BuildInfo at startup to extract VCS revision. Not applicable to .NET.
VERSION = "2.14.0-dev" const.go:69 PARTIAL src/NATS.Server/Protocol/NatsProtocol.cs:11 .NET has Version = "0.1.0". The version string is present but does not match Go's version.
PROTO = 1 const.go:76 PORTED src/NATS.Server/Protocol/NatsProtocol.cs:12 ProtoVersion = 1
DEFAULT_PORT = 4222 const.go:79 PORTED src/NATS.Server/Protocol/NatsProtocol.cs:10 DefaultPort = 4222
RANDOM_PORT = -1 const.go:83 NOT_APPLICABLE Used in Go test helpers to request a random port. .NET tests use GetFreePort() pattern.
DEFAULT_HOST = "0.0.0.0" const.go:86 PORTED src/NATS.Server/Protocol/NatsProtocol.cs:11 Added NatsProtocol.DefaultHost and wired NatsOptions.Host default to it.
MAX_CONTROL_LINE_SIZE = 4096 const.go:91 PORTED src/NATS.Server/Protocol/NatsProtocol.cs:7 MaxControlLineSize = 4096
MAX_PAYLOAD_SIZE = 1MB const.go:95 PORTED src/NATS.Server/Protocol/NatsProtocol.cs:8 MaxPayloadSize = 1024 * 1024
MAX_PAYLOAD_MAX_SIZE = 8MB const.go:99 PORTED src/NATS.Server/Protocol/NatsProtocol.cs:9 Added NatsProtocol.MaxPayloadMaxSize (8MB threshold constant).
MAX_PENDING_SIZE = 64MB const.go:103 PORTED src/NATS.Server/Protocol/NatsProtocol.cs:9 MaxPendingSize = 64 * 1024 * 1024
DEFAULT_MAX_CONNECTIONS = 64K const.go:106 PORTED src/NATS.Server/Protocol/NatsProtocol.cs:13 Added NatsProtocol.DefaultMaxConnections and wired NatsOptions.MaxConnections.
TLS_TIMEOUT = 2s const.go:109 PORTED src/NATS.Server/Protocol/NatsProtocol.cs:18, src/NATS.Server/NatsOptions.cs:102 Added protocol default and wired TLS timeout default in options.
DEFAULT_TLS_HANDSHAKE_FIRST_FALLBACK_DELAY = 50ms const.go:114 PORTED src/NATS.Server/Protocol/NatsProtocol.cs:19, src/NATS.Server/NatsOptions.cs:104 Added protocol default and wired TlsHandshakeFirstFallback default in options.
AUTH_TIMEOUT = 2s const.go:118 PORTED src/NATS.Server/Protocol/NatsProtocol.cs:20, src/NATS.Server/NatsOptions.cs:49 Added protocol default and wired AuthTimeout default in options.
DEFAULT_PING_INTERVAL = 2min const.go:122 PORTED src/NATS.Server/Protocol/NatsProtocol.cs:21, src/NATS.Server/NatsOptions.cs:19 Added protocol default and wired PingInterval default in options.
DEFAULT_PING_MAX_OUT = 2 const.go:125 PORTED src/NATS.Server/Protocol/NatsProtocol.cs:14, src/NATS.Server/NatsOptions.cs:20 Added protocol default and wired MaxPingsOut default in options.
CR_LF = "\r\n" const.go:128 PORTED src/NATS.Server/Protocol/NatsProtocol.cs:15 CrLf byte array.
LEN_CR_LF = 2 const.go:131 PORTED Implicit in .NET (+ 2 literals in parser). Used as literal 2 in TryReadPayload.
DEFAULT_FLUSH_DEADLINE = 10s const.go:134 PORTED src/NATS.Server/Protocol/NatsProtocol.cs:22, src/NATS.Server/NatsOptions.cs:18 Added protocol default and wired WriteDeadline default in options.
DEFAULT_HTTP_PORT = 8222 const.go:137 PORTED src/NATS.Server/Protocol/NatsProtocol.cs:15 Added NatsProtocol.DefaultHttpPort constant and parity assertions in protocol constants tests.
DEFAULT_HTTP_BASE_PATH = "/" const.go:140 PORTED src/NATS.Server/Protocol/NatsProtocol.cs:16 Added NatsProtocol.DefaultHttpBasePath constant and parity assertions in protocol constants tests.
ACCEPT_MIN_SLEEP = 10ms const.go:143 PORTED src/NATS.Server/Protocol/NatsProtocol.cs:23, src/NATS.Server/NatsServer.cs:94 Added protocol default and wired accept-loop backoff minimum in server.
ACCEPT_MAX_SLEEP = 1s const.go:146 PORTED src/NATS.Server/Protocol/NatsProtocol.cs:24, src/NATS.Server/NatsServer.cs:95 Added protocol default and wired accept-loop backoff maximum in server.
DEFAULT_ROUTE_CONNECT = 1s const.go:149 PORTED src/NATS.Server/Protocol/NatsProtocol.cs:31 Added NatsProtocol.DefaultRouteConnect constant.
DEFAULT_ROUTE_CONNECT_MAX = 30s const.go:152 PORTED src/NATS.Server/Protocol/NatsProtocol.cs:32 Added NatsProtocol.DefaultRouteConnectMax constant.
DEFAULT_ROUTE_RECONNECT = 1s const.go:155 PORTED src/NATS.Server/Protocol/NatsProtocol.cs:33 Added NatsProtocol.DefaultRouteReconnect constant.
DEFAULT_ROUTE_DIAL = 1s const.go:158 PORTED src/NATS.Server/Protocol/NatsProtocol.cs:34 Added NatsProtocol.DefaultRouteDial constant.
DEFAULT_ROUTE_POOL_SIZE = 3 const.go:161 PORTED src/NATS.Server/Protocol/NatsProtocol.cs:17 Added NatsProtocol.DefaultRoutePoolSize constant.
DEFAULT_LEAF_NODE_RECONNECT = 1s const.go:164 PORTED src/NATS.Server/Protocol/NatsProtocol.cs:35 Added NatsProtocol.DefaultLeafNodeReconnect constant.
DEFAULT_LEAF_TLS_TIMEOUT = 2s const.go:167 PORTED src/NATS.Server/Protocol/NatsProtocol.cs:36 Added NatsProtocol.DefaultLeafTlsTimeout constant.
PROTO_SNIPPET_SIZE = 32 const.go:170 PORTED src/NATS.Server/Protocol/NatsProtocol.cs:9, src/NATS.Server/Protocol/NatsParser.cs:222 Added snippet-size constant and wired parser default ProtoSnippet overload to it.
MAX_CONTROL_LINE_SNIPPET_SIZE = 128 const.go:172 PORTED src/NATS.Server/Protocol/NatsProtocol.cs:8, src/NATS.Server/Protocol/NatsParser.cs:85 Added max control-line snippet size constant and wired control-line violation errors to use it.
MAX_MSG_ARGS = 4 const.go:175 NOT_APPLICABLE Used in Go's manual arg-split loop. .NET uses SplitArgs() with stack-allocated ranges.
MAX_RMSG_ARGS = 6 const.go:178 NOT_APPLICABLE Used in RMSG parsing. RMSG not yet ported.
MAX_HMSG_ARGS = 7 const.go:180 NOT_APPLICABLE Used in HMSG parsing. HMSG routing not yet ported.
MAX_PUB_ARGS = 3 const.go:183 NOT_APPLICABLE Used in PUB arg splitting. .NET uses dynamic SplitArgs.
MAX_HPUB_ARGS = 4 const.go:186 NOT_APPLICABLE Used in HPUB arg splitting. .NET uses dynamic SplitArgs.
MAX_RSUB_ARGS = 6 const.go:189 NOT_APPLICABLE Used in RS+/LS+ subscription arg splitting. Not yet ported.
DEFAULT_MAX_CLOSED_CLIENTS = 10000 const.go:192 PORTED src/NATS.Server/Protocol/NatsProtocol.cs:15, src/NATS.Server/NatsOptions.cs:89 Added protocol default and wired closed-client ring size default in options.
DEFAULT_LAME_DUCK_DURATION = 2min const.go:196 PORTED src/NATS.Server/Protocol/NatsProtocol.cs:25, src/NATS.Server/NatsOptions.cs:59 Added protocol default and wired lame-duck duration default in options.
DEFAULT_LAME_DUCK_GRACE_PERIOD = 10s const.go:200 PORTED src/NATS.Server/Protocol/NatsProtocol.cs:26, src/NATS.Server/NatsOptions.cs:60 Added protocol default and wired lame-duck grace period default in options.
DEFAULT_LEAFNODE_INFO_WAIT = 1s const.go:203 PORTED src/NATS.Server/Protocol/NatsProtocol.cs:37 Added NatsProtocol.DefaultLeafNodeInfoWait constant.
DEFAULT_LEAFNODE_PORT = 7422 const.go:206 PORTED src/NATS.Server/Protocol/NatsProtocol.cs:18 Added NatsProtocol.DefaultLeafNodePort constant.
DEFAULT_CONNECT_ERROR_REPORTS = 3600 const.go:214 PORTED src/NATS.Server/Protocol/NatsProtocol.cs:16, src/NATS.Server/NatsOptions.cs:86 Added protocol default and wired ConnectErrorReports default in options.
DEFAULT_RECONNECT_ERROR_REPORTS = 1 const.go:220 PORTED src/NATS.Server/Protocol/NatsProtocol.cs:17, src/NATS.Server/NatsOptions.cs:87 Added protocol default and wired ReconnectErrorReports default in options.
DEFAULT_RTT_MEASUREMENT_INTERVAL = 1h const.go:224 PORTED src/NATS.Server/Protocol/NatsProtocol.cs:38 Added NatsProtocol.DefaultRttMeasurementInterval constant.
DEFAULT_ALLOW_RESPONSE_MAX_MSGS = 1 const.go:228 PORTED src/NATS.Server/Protocol/NatsProtocol.cs:24 Added NatsProtocol.DefaultAllowResponseMaxMsgs constant.
DEFAULT_ALLOW_RESPONSE_EXPIRATION = 2min const.go:232 PORTED src/NATS.Server/Protocol/NatsProtocol.cs:39 Added NatsProtocol.DefaultAllowResponseExpiration constant.
DEFAULT_SERVICE_EXPORT_RESPONSE_THRESHOLD = 2min const.go:237 PORTED src/NATS.Server/Protocol/NatsProtocol.cs:40 Added NatsProtocol.DefaultServiceExportResponseThreshold constant.
DEFAULT_SERVICE_LATENCY_SAMPLING = 100 const.go:241 PORTED src/NATS.Server/Protocol/NatsProtocol.cs:25 Added NatsProtocol.DefaultServiceLatencySampling constant.
DEFAULT_SYSTEM_ACCOUNT = "$SYS" const.go:244 PORTED src/NATS.Server/Protocol/NatsProtocol.cs:26, src/NATS.Server/Auth/Account.cs:10 Added protocol-level constant; existing account model uses the same value ($SYS).
DEFAULT_GLOBAL_ACCOUNT = "$G" const.go:247 PORTED src/NATS.Server/Protocol/NatsProtocol.cs:27 Added NatsProtocol.DefaultGlobalAccount constant.
DEFAULT_ACCOUNT_FETCH_TIMEOUT = 1900ms const.go:250 PORTED src/NATS.Server/Protocol/NatsProtocol.cs:41 Added NatsProtocol.DefaultAccountFetchTimeout constant.

.NET-Only Additions (no Go counterpart in the three source files)

.NET Symbol .NET File:Line Status Notes
NatsHeaderParser src/NATS.Server/Protocol/NatsHeaderParser.cs:20 PORTED Parses NATS/1.0 header blocks. Go uses http.Header/textproto lazily from getHeader() on parseState. .NET provides an eager standalone parser.
NatsHeaders (struct) src/NATS.Server/Protocol/NatsHeaderParser.cs:6 PORTED Structured result for parsed NATS headers (status, description, key-value map). No direct Go counterpart — Go uses http.Header directly.
ClientCommandMatrix src/NATS.Server/Protocol/ClientCommandMatrix.cs:4 PORTED Encodes which inter-server opcodes (RS+, RS-, RMSG, A+, A-, LS+, LS-, LMSG) are allowed per client kind. Corresponds to the switch c.kind / switch c.op dispatch inside parse().
MessageTraceContext src/NATS.Server/Protocol/MessageTraceContext.cs:3 PORTED Captures client name/lang/version/headers from CONNECT options for trace logging. Equivalent to fields inside Go's client struct populated during processConnect.
ProxyProtocolParser src/NATS.Server/Protocol/ProxyProtocol.cs:48 PORTED PROXY protocol v1/v2 pure-parser. Corresponds to client_proxyproto.go (not in the three listed source files, but closely related to the protocol module).
ProxyAddress, ProxyParseResult, ProxyParseResultKind src/NATS.Server/Protocol/ProxyProtocol.cs:11 PORTED Supporting types for PROXY protocol parsing.
ServerInfo (class) src/NATS.Server/Protocol/NatsProtocol.cs:39 PORTED Wire-format INFO message JSON model. Corresponds to Go's Info struct in server.go.
ClientOptions (class) src/NATS.Server/Protocol/NatsProtocol.cs:98 PARTIAL Wire-format CONNECT options JSON model. Missing: nkey, sig, jwt fields present but auth handling not implemented server-side.

Keeping This File Updated

After porting work is completed:

  1. Update status: Change MISSING → PORTED or PARTIAL → PORTED for each item completed
  2. Add .NET path: Fill in the ".NET Equivalent" column with the actual file:line
  3. Re-count LOC: Update the LOC numbers in stillmissing.md:
    # Re-count .NET source LOC for this module
    find src/NATS.Server/Protocol/ -name '*.cs' -type f -exec cat {} + | wc -l
    # Re-count .NET test LOC for this module
    find tests/NATS.Server.Tests/Protocol/ -name '*.cs' -type f -exec cat {} + | wc -l
    
  4. Add a changelog entry below with date and summary of what was ported
  5. Update the parity DB if new test mappings were created:
    sqlite3 docs/test_parity.db "INSERT INTO test_mappings (go_test_id, dotnet_test_id, confidence, notes) VALUES (?, ?, 'manual', 'ported in YYYY-MM-DD session')"
    

Test Cross-Reference Summary

Go test file: parser_test.go

Go Test Status .NET Equivalent
TestParsePing PARTIAL tests/NATS.Server.Tests/ParserTests.cs: Parse_PING — covers full PING\r\n; missing byte-by-byte incremental state assertions
TestParsePong PARTIAL tests/NATS.Server.Tests/ParserTests.cs: Parse_PONG — covers full PONG\r\n; missing ping.out counter decrement test
TestParseConnect PORTED tests/NATS.Server.Tests/ParserTests.cs: Parse_CONNECT
TestParseSub PORTED tests/NATS.Server.Tests/ParserTests.cs: Parse_SUB_without_queue, Parse_SUB_with_queue
TestParsePub PARTIAL tests/NATS.Server.Tests/ParserTests.cs: Parse_PUB_with_payload, Parse_PUB_with_reply — missing overflow payload error scenario
TestParsePubSizeOverflow PORTED tests/NATS.Server.Tests/ParserTests.cs: Parse_pub_size_overflow_fails — explicit oversized PUB payload-size argument test now asserts parser rejection (Invalid payload size)
TestParsePubArg PORTED tests/NATS.Server.Tests/ParserTests.cs: Parse_PUB_argument_variations (Theory)
TestParsePubBadSize PARTIAL tests/NATS.Server.Tests/ParserTests.cs: Parse_malformed_protocol_fails covers some bad args; missing specific mpay (max payload per-client) test
TestParseHeaderPub PORTED tests/NATS.Server.Tests/ParserTests.cs: Parse_HPUB
TestParseHeaderPubArg MISSING No .NET Theory equivalent for the 32 HPUB argument variations with mixed spaces/tabs
TestParseRoutedHeaderMsg (HMSG) MISSING No .NET equivalent — ROUTER/GATEWAY HMSG parsing not yet ported
TestParseRouteMsg (RMSG) MISSING No .NET equivalent — ROUTER RMSG parsing not yet ported
TestParseMsgSpace MISSING No .NET equivalent — MSG opcode for routes not yet ported
TestShouldFail PARTIAL tests/NATS.Server.Tests/ParserTests.cs: Parse_malformed_protocol_fails — covers subset; documented behavioral differences for byte-by-byte vs prefix-scan parser
TestProtoSnippet PORTED tests/NATS.Server.Tests/Protocol/ProtocolParserSnippetGapParityTests.cs: ProtoSnippet_* validates Go-style snippet behavior and parser error context wiring.
TestParseOK PORTED tests/NATS.Server.Tests/ParserTests.cs: Parse_case_insensitive includes +OK (via ParsedCommand.Simple)
TestMaxControlLine PARTIAL tests/NATS.Server.Tests/ParserTests.cs: Parse_exceeding_max_control_line_fails — covers basic enforcement; missing per-client-kind bypass (LEAF/ROUTER/GATEWAY exempt)

Go test file: split_test.go

Go Test Status .NET Equivalent
TestSplitBufferSubOp PARTIAL tests/NATS.Server.Tests/ParserTests.csSystem.IO.Pipelines handles split buffers transparently; no explicit split-state test
TestSplitBufferUnsubOp PARTIAL Same as above
TestSplitBufferPubOpTestSplitBufferPubOp5 PARTIAL Parse_PUB_with_payload covers basic case; no multi-chunk split test
TestSplitConnectArg PARTIAL No explicit argBuf accumulation test
TestSplitDanglingArgBuf NOT_APPLICABLE .NET parser has no argBuf — pipeline buffering makes this moot
TestSplitRoutedMsgArg MISSING RMSG not yet ported
TestSplitBufferMsgOp MISSING RMSG not yet ported
TestSplitBufferLeafMsgArg MISSING LMSG (leaf) not yet ported

Go test file: parser_fuzz_test.go

Go Test Status .NET Equivalent
FuzzParser MISSING No .NET fuzz test. Could be approximated with property-based testing ([Theory] with random inputs via FsCheck or Bogus).

Go test file: server_fuzz_test.go

Go Test Status .NET Equivalent
FuzzServerTLS MISSING TLS-first handshake and TLS fuzzing not yet implemented in .NET server.

Go test file: subject_fuzz_test.go

Go Test Status .NET Equivalent
FuzzSubjectsCollide MISSING SubjectsCollide() function not yet ported. .NET has SubjectMatch.IsValidSubject() and wildcard matching but not a SubjectsCollide API.

Change Log

Date Change By
2026-02-26 Added parser overflow parity test (Parse_pub_size_overflow_fails) and reclassified TestParsePubSizeOverflow from MISSING to PORTED. codex
2026-02-25 File created with LLM analysis instructions auto
2026-02-25 Full gap inventory populated: parser.go, proto.go, const.go; test cross-reference for all 5 Go test files claude-sonnet-4-6
2026-02-25 Executed protocol defaults parity batch: introduced missing const/default surfaces in NatsProtocol, wired NatsOptions and accept-loop defaults, added targeted tests (ProtocolDefaultConstantsGapParityTests), and reclassified 16 const.go rows from MISSING to PORTED codex
2026-02-25 Executed protocol proto-wire parity batch: added ProtoWire scanners/encoder and parity tests (ProtoWireParityTests), and reclassified all 9 proto.go rows from MISSING to PORTED codex