- Add legacy alias support for backward compatibility - Update ProtocolBuffer message definitions with new fields - Implement fullname-based message routing - Add alias fallback logic in all language clients (Dart, Go, Kotlin, Python, TypeScript) - Update test suites for alias and fullname validation - Add protocol sync verification tools - Update documentation (PORTING_GUIDE, PROTOCOL, VERSIONING) - Add agent task documentation for protocol evolution
4.9 KiB
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 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
PacketBaseprotobuf payload. - WebSocket and WSS use one binary frame per
PacketBaseprotobuf payload. PacketBase.typeNameroutes the inner message by canonical protobuf full message name.nonceincrements for every outbound packet on a connection.responseNoncelinks 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
PacketBasefields. - Changing the canonical proto package or
typeNamederivation without a compatibility path. - Changing
nonceorresponseNoncesemantics. - 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.
Backward-compatible message additions require updated parser maps and cross-language tests before release.
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
1and increment by1on every send call, including requests and responses. - After issuing
2,147,483,647, implementations reset the internal counter to0; the next emittedPacketBase.nonceis1. 0is reserved and must not be emitted asPacketBase.nonce, becauseresponseNonce == 0means "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
typeNamevalues 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
nonceandresponseNonce. - Handle heartbeat automatically inside the client/server core.
- Pass same-language tests and cross-language tests against at least one available implementation.