10 KiB
DGR-002 — Versioned gRPC Shard protocol: evidence
Status: done Date: 2026-07-15 Evidence kind: synthetic-unit (schema round-trip + cross-language protobuf compatibility). No model download, no GPU, no network, no API credits.
Summary
Added the versioned Protocol Buffers schema that is the semantic contract between Python and C++ Shards (ADR-0024), plus reproducible Python and C++ code generation/build wiring and generated-schema round-trip + compatibility tests in both languages. The schema defines one long-lived bidirectional gRPC stream per Route Session Activation Seam, bounded prefill chunking, a small decode fast path, and a versioned named-tensor bundle carrying every required identifier.
No existing runtime code was modified — this story is purely additive (a new
.proto, a native_protocol loader package, C++ build wiring, and one new test
module). Generated stubs are produced on demand into gitignored build/
directories, so nothing generated is committed.
Files changed (all new)
packages/node/native/proto/shard_runtime.proto— the schema (packagemeshnet.shard.v1, proto3). ServiceShardRuntimewithGetCapability,Health,ActivateSession(bidi stream),Release,Cancel.packages/node/meshnet_node/native_protocol/__init__.py— reproducible on-demandgrpc_tools.protoccodegen + loader (load(),load_grpc()) and shared bundle helpers (compute_checksum,verify_checksum,fragment_tensor,reassemble_tensor).packages/node/native/scripts/generate_python.py— standalone reproducible Python generation (self-contained; does not importmeshnet_node).packages/node/native/scripts/generate_cpp.sh— reproducible C++ generation (message stubs always; gRPC service stubs whengrpc_cpp_pluginis present).packages/node/native/CMakeLists.txt— C++ build wiring; works with both CONFIG-mode (protobuf::libprotobuf/protobuf::protoc) and CMake'sFindProtobufmodule.packages/node/native/tests/roundtrip_test.cpp— C++ round-trip / compat test (--selftest,--read,--write).tests/test_native_shard_protocol.py— Python round-trip + compatibility tests and the Python↔C++ cross-language driver.
Acceptance criteria → evidence
- Capability/health/session-stream/release/cancellation schema — the
ShardRuntimeservice's five RPCs;test_capability_and_health_round_trip,test_session_stream_carries_open_prefill_decode_release_cancel. - One long-lived bidi stream per Activation Seam with deadlines, cancellation,
flow control, structured errors —
rpc ActivateSession (stream ...) returns (stream ...). Deadlines: gRPC call deadline on direct transport, plusSessionOpen.deadline_unix_nanosfor relay-carried frames. Cancellation:CancelRPC and in-streamCancelRequest/PHASE_CANCEL. Flow control:FlowControlframes (credits + in-flight byte/message caps). Structured errors:Status(canonical code, message,RetryClass, details). Verified bytest_session_response_carries_structured_status_and_results. - Bounded prefill chunking + small decode fast path —
PrefillChunk(chunk_index/chunk_count/final_chunk,SessionOpen.max_prefill_tokens_per_chunk) andDecodeStep(minimal single-bundle path). Bounded fragments viaSessionOpen.max_fragment_bytesandfragment_tensor(...). - Carries schema version, work ID, Route Session ID, route epoch,
artifact/recipe fingerprint, shard range/effective start, phase, position,
idempotency step, cache expectation, compression, checksum — all on
MessageHeader(+ArtifactFingerprint.runtime_recipe_fingerprint,ShardRange.effective_start_layer). Verified field-by-field bytest_message_header_carries_every_required_field. - Versioned named-tensor bundle (name, shape, dtype, byte order, fragments) —
TensorBundle/NamedTensor/TensorFragment;test_named_tensor_bundle_describes_shape_dtype_byteorder_and_fragments,test_fragment_and_reassemble_round_trip_with_checksums. - Round-trip + compatibility tests in Python and C++ — Python:
tests/test_native_shard_protocol.py(11 tests). C++:roundtrip_test.cppbuilt via CMake; cross-language drivertest_cross_language_roundtrip_python_and_cppexercises Python→C++ and C++→Python in both directions. - Targeted pytest —
11 passed, 1 skipped(default env);12 passedwith the C++ toolchain on PATH. - compileall packages tests — exit 0.
- git diff --check — clean.
- Deterministic / download-free / credit-free / GPU-free — all tests are pure protobuf serialization; the C++ path uses only local compilers.
- Full deterministic pytest —
704 passed, 14 skipped, 11 failed. The 11 failures are pre-existing and unrelated (see below).
Commands and real results
See commands.txt for the exact command list. Key results:
python packages/node/native/scripts/generate_python.py→shard_runtime_pb2.py: ok,shard_runtime_pb2_grpc.py: ok.pytest tests/test_native_shard_protocol.py -q→ 11 passed, 1 skipped (skip reason:C++ toolchain unavailable: cmake not found on PATH).- With
/tmp/pbsrc/install/bin(protoc 33.1) and.venv/bin(cmake) on PATH andCMAKE_PREFIX_PATH=/tmp/pbsrc/install:generate_cpp.sh→shard_runtime.pb.cc,shard_runtime.pb.h(grpc service stubs skipped:grpc_cpp_pluginabsent).cmake -S ... -B ...+cmake --build ...→ build OK.shard_protocol_roundtrip_test --selftest→selftest ok (128 bytes), exit 0.ctest→1/1 Test #1: shard_protocol_roundtrip ... Passed.pytest ...::test_cross_language_roundtrip_python_and_cpp -q→ 1 passed (Python serializes → C++ parses & verifies → C++ serializes → Python parses & verifies).
compileall -q packages tests→ exit 0.git diff --check→ clean.
Pre-existing unrelated failures (full-suite)
pytest -q on the full tree reports 11 failures, all in tracker routing /
dynamic routing / manual route benchmark / toploc calibration — none import the
Shard protocol. Clean-tree reproduction: with all DGR-002 files moved aside
(git status shows only the pre-existing .ralph-tui/config.toml deletion),
re-running exactly these tests gives 11 failed, 3 passed — identical failures.
They exist on the ralph/distributed-gguf-runtime branch independent of this
story. The full list is in results.json.preexisting_unrelated_failures.
Note: the earlier progress.md (RCR-001, on master) recorded a different set of
6 optional-dependency failures (zstandard, langchain_openai). Those did not
recur here; this environment has those deps. The 11 above are branch-local
routing/benchmark failures, not environmental.
Limitations and deferred work
- C++ toolchain is host-provided, not vendored. The default test env has no
protoc/cmake/protobuf C++ headers on PATH, so the C++ cross-language test skips by default (explicit skip reason). It was executed for this evidence using an ephemeral from-source protobuf 33.1 install at/tmp/pbsrc/installplus the.venvcmake. DGR-004/DGR-008 should pin the C++ protobuf/gRPC toolchain (upstream commit + reproducible fetch/build) so this test runs in CI without relying on an ad-hoc/tmpinstall. - gRPC C++ service stubs not built here.
grpc_cpp_pluginis absent, sogenerate_cpp.shproduced message stubs only. The round-trip test needs only message serialization; the service stubs are DGR-008's concern. - No live gRPC transport yet. This story delivers the schema + serialization contract and generation/build wiring only. Channel setup, the bidi stream server/client, deadlines/cancellation propagation over a real HTTP/2 channel, and relay framing are DGR-008/DGR-009.
- Protobuf runtime version skew. Python runtime is pip protobuf 7.35.1; the C++ side used protoc 33.1. Protobuf wire format is stable across these, and the cross-language round-trip confirms interop; version pinning is deferred to the toolchain-pinning stories.
Compatibility / migration notes
- proto3 with a 0-valued
*_UNSPECIFIEDmember on every enum and never-reused field numbers. Forward compatibility (unknown-field preservation) is verified behaviourally bytest_unknown_fields_are_preserved_for_forward_compatibility— note protobuf 7.x's upb backend does not implement theUnknownFields()introspection accessor, so the test asserts the observable re-serialization outcome instead. Backward defaults verified bytest_defaults_are_stable_for_backward_compatibility. - Wire schema version is
SchemaVersion.SCHEMA_VERSION_1(int 1), also exposed asmeshnet_node.native_protocol.SCHEMA_VERSION.
Handoff for dependent stories
- DGR-003 (recipe/fingerprint): populate
ArtifactFingerprint(model_id,revision,artifact_hash,quantization,runtime_recipe_fingerprint). Admission compares these before activation; a mismatch is a fatalStatus(RetryClass.RETRY_CLASS_FATAL). - DGR-004 (llama.cpp pin) / DGR-008 (C++ worker): pin the C++
protobuf + gRPC toolchain and add
grpc_cpp_plugin; thengenerate_cpp.shemits service stubs and the CMake target can link gRPC. Implement theShardRuntimeservicer; map(route_session_id, route_epoch)to an isolated llama sequence. UseSessionOpenfor stream-scoped bounds andFlowControlfor backpressure. - DGR-009 (Meshnet integration/relay): the relay may carry serialized
SessionActivation/SessionResponseframes as opaque binary; use the in-messagedeadline_unix_nanos,CancelRequest, andFlowControlsince gRPC call metadata is lost over relay. - Loader usage:
from meshnet_node import native_protocol as proto; pb2 = proto.load(). Stubs regenerate automatically when the.protochanges (mtime check).proto.load_grpc()returns the service stubs (needs thegrpcruntime). - Gotcha: the
.venvinstalls the meshnet packages editable via a PEP 660 meta-path finder pointing at the main checkout. Import the worktree copy by ensuring the worktreepackages/nodeis onsys.pathfirst (conftest already does this for pytest); standalone tooling must derive paths from__file__and notimport meshnet_node(whygenerate_python.pyis self-contained).