# Versioning Proto Socket tracks protocol compatibility separately from language package versions. ## Current Versions - Protocol version: `0.1` - Dart package version: see `dart/pubspec.yaml` - Go module version: repository tag based `0.1` is the current compatibility contract for the checked-in available implementations. The wire format does not carry a protocol version field yet; compatibility is verified by shared proto definitions, unit tests, and cross-language tests. Protocol `0.1` also allows optional application-level convention messages for capability announcement and request error reporting. These conventions do not change the required handshake or the `PacketBase` wire fields unless they are promoted in a later protocol version. ## Protocol Version The protocol version describes the wire-format and behavior contract that every language implementation must satisfy: - TCP uses a 4-byte big-endian payload length followed by one `PacketBase` protobuf payload. - WebSocket and WSS use one binary frame per `PacketBase` protobuf payload. - `PacketBase.typeName` routes the inner message by canonical protobuf full message name. - `nonce` increments for every outbound packet on a connection. - `responseNonce` links a response packet to the request nonce. - Heartbeat behavior follows `PROTOCOL.md`. Breaking protocol changes require a new major protocol version. Backward-compatible additions keep the same major protocol version but must include updated tests before release. ## Proto Package and Wire Identity Proto package names are part of the wire identity because they prefix protobuf full message names. Package names must use lowercase snake_case segments joined by dots, for example `proto_socket` or `example_chat.v1`. The canonical package for the shared packet schema is `proto_socket`. Common message identities therefore use values such as `proto_socket.PacketBase`, `proto_socket.HeartBeat`, and `proto_socket.TestData`; `PacketBase.typeName` carries the inner message identity. Language-specific namespace options such as Go `go_package` or Java/Kotlin package names are package-generation details. They do not change the protocol package or wire `typeName`. ## Git Release Standard Current consumption and release flow is Git ref/tag based. Package registry publication is optional future work, not the current release standard. Git releases must identify the repository ref/tag being consumed and use the full local validation matrix as the compatibility gate. ## Package Version Each language implementation may publish on its own package cadence if registry releases are later introduced. Package versions communicate implementation releases, bug fixes, and language-specific API changes. A package release must state which protocol version it implements. A package version bump does not imply a protocol version bump unless the wire-format or required behavior changes. ## Breaking Protocol Changes Examples of breaking protocol changes: - Renaming or removing `PacketBase` fields. - Changing the canonical proto package or `typeName` derivation without a compatibility path. - Changing `nonce` or `responseNonce` semantics. - Changing heartbeat request/response timing or echo behavior in a way that disconnects older peers. - Changing TCP framing, byte order, max packet handling, or WebSocket binary-frame rules. ## Non-breaking Protocol Changes Examples of non-breaking changes: - Adding a new protobuf message type. - Adding optional fields to application messages when older peers can ignore them. - Adding a new language implementation that passes the existing protocol and cross-language tests. - Tightening tests or documentation without changing wire behavior. - Adding an optional hello/capability message that peers may ignore and that is not required before normal traffic. - Adding an optional standard error response convention, provided older peers can still fail by timeout or existing response type-mismatch behavior. Backward-compatible message additions require updated parser maps and cross-language tests before release. ## Optional Capability Announcement `ProtoSocketHello`, or an equivalent project-specific message, is a candidate convention for announcing: - `protocolVersion` - stable `capabilities` tokens - optional implementation metadata In protocol `0.1`, this message is not a required handshake. A peer must be able to send and receive normal messages without first receiving a hello/capability message. Making a hello message mandatory, changing connection readiness semantics, or disconnecting older peers that do not send it requires a protocol-version review. ## Standard Error Response Convention `ProtoSocketError`, or an equivalent project-specific message, is a candidate convention for request handler failures. A supported error response should carry the original request nonce in `responseNonce`, a stable error code, a safe message, and optional detail/debug fields. In protocol `0.1`, implementations may continue to report handler failure as timeout, response type mismatch, or implementation-specific errors. Requiring all handlers to emit a shared error response, or requiring every requester to treat a particular error message type specially, requires parser map updates, cross-language tests, and compatibility review. ## nonce Overflow `nonce` and `responseNonce` fields are protobuf `int32` values (signed 32-bit). The maximum emitted nonce is `2,147,483,647` (`int32` max). Current policy: - Implementations start at `1` and increment by `1` on every send call, including requests and responses. - When selecting the next nonce to emit, implementations must skip any value that is currently used by an active pending request (`sendRequest` correlation map). This keeps nonce reuse from colliding with in-flight requests after wrap. - If all positive `int32` nonce values are currently pending, `sendRequest`/`send` must fail explicitly rather than emit a duplicate correlation nonce. - After issuing `2,147,483,647`, implementations reset the internal counter to `0`; the next emitted `PacketBase.nonce` is `1`. - `0` is reserved and must not be emitted as `PacketBase.nonce`, because `responseNonce == 0` means "not a response". Changing this wrap behavior or the reserved meaning of `responseNonce == 0` changes `nonce` semantics and requires compatibility review and cross-language boundary tests. ## New Language Compatibility A new language implementation must target the current protocol version unless its README explicitly says otherwise. Before it is listed as available, it must: - Generate protobuf bindings from the canonical schema. - Use the same canonical protobuf full message name `typeName` values as the available implementations. - Keep language namespace/package options separate from the protobuf package used for wire identity. - Implement TCP, TLS+TCP, WS, and WSS framing consistently where the language runtime supports them. - Implement request-response correlation with `nonce` and `responseNonce`. - Handle heartbeat automatically inside the client/server core. - Pass same-language tests and cross-language tests against at least one available implementation.