v0.18.0
Application protocol_version enforcement
Introduces a per-Protocol surface version that vgi-rpc validates on every dispatched RPC. A Protocol that declares protocol_version: ClassVar[str] = "X.Y.Z" opts in; the framework emits vgi_rpc.protocol_version on every request batch's custom_metadata; the server enforces exact major+minor match (patch ignored) at the dispatch boundary on every transport (pipe / HTTP / unix / subprocess). Mismatches raise ProtocolVersionError with a directional message telling the reader which side to upgrade.
This is distinct from REQUEST_VERSION (wire framing, vgi-rpc's concern) and from per-catalog data-version semantics. It versions the method-and-schema contract between client and worker — the thing a C++ extension or Rust port has to keep in sync with the Python reference Protocol.
What's new
protocol_versionClassVar onProtocolsubclasses. Read viavars()(notgetattr) so subclasses that don't redeclare getNoneand opt out cleanly — no inheritance leaks. Validated at server / client construction; malformed semver raisesValueErrorat construction, not first RPC.vgi_rpc.protocol_versionrequest metadata key. Carried on every request batch from a vgi-rpcRpcClientbound to a Protocol that declares the version. Surfaced in__describe__response metadata so mismatched clients can introspect the server's expected version.ProtocolVersionError(subclass ofVersionError,error_kind="protocol_version_mismatch") with four directional templates: client-too-old, server-too-old, malformed, missing.- Dispatch-boundary enforcement on every transport.
RpcServer.serve_onefor pipe / subprocess / unix;_run_unary_syncand_run_stream_init_syncfor HTTP.__describe__is exempt so version-mismatched clients can still introspect. ConformanceService.protocol_version = "1.0.0"— cross-language ports (Go / TS / Java / Rust) must add the metadata key to claim conformance. Three new conformance tests:describe_protocol_version.surfaces_declared_version,describe_protocol_version.format,protocol_version.matched_dispatch_succeeds.
Breaking changes
- Operator-supplied
RpcServer(protocol_version="...")kwarg removed. This was a free-form access-log label with no enforcement and no observed consumers; the name is reused for the new strict-semver mechanism declared on the Protocol class. Pre-release, no deprecation shim. Operators relying on the access-logprotocol_versionfield must remove it from parsers. protocol_versionfield removed from access log JSON schema (vgi_rpc/access_log.schema.json,docs/access-log-spec.md). The new mechanism is enforced at the wire layer; access-log emission of the value is no longer load-bearing.
Cross-language source of truth
For ports that can't import vgi_rpc, the canonical version string for ConformanceService ships at https://github.com/Query-farm/vgi-rpc-python/blob/main/vgi_rpc/conformance/_protocol.py — and the Protocol class is the source of truth on the Python side. Bumping the version requires:
- Update
protocol_versionon the Protocol class. - Cross-language ports re-read the metadata key on every request.
- Conformance suite enforces parity.
Known issues
http_externalize_alwaysconformance variant is skipped on Windows for now. A pre-existing TCP race between waitress and httpx (WinError 10053) surfaces deterministically on Windows when the new metadata key shifts request-batch timing past a margin that v0.17.1 happened to clear by luck. Linux / macOS keep full coverage of this variant. The underlying race needs a framework-side fix (drain WSGI response body before close) and will be addressed in a follow-up.
Files
vgi_rpc/metadata.py—PROTOCOL_VERSION_KEY,parse_version,SEMVER_REGEXvgi_rpc/rpc/_server.py—_check_protocol_version, dispatch-boundary gate,ProtocolVersionErrorraisevgi_rpc/rpc/_client.py,vgi_rpc/http/_client.py— request-time emissionvgi_rpc/http/server/_app_unary.py,_app_stream.py— HTTP dispatch-boundary gatevgi_rpc/conformance/_protocol.py—protocol_version = "1.0.0"vgi_rpc/conformance/_runner.py— describe + matched-dispatch teststests/test_protocol_version.py— 45 unit tests covering pipe and HTTP, comparison matrix, inheritance, malformed, directional error messages