fix: harden DGR-002 protocol bounds
This commit is contained in:
@@ -38,7 +38,7 @@ New:
|
||||
|
||||
| Path | What |
|
||||
|---|---|
|
||||
| `packages/node/native/proto/shard_runtime.proto` | The schema (sha256 `077ee349…`, see `protocol.json`) |
|
||||
| `packages/node/native/proto/shard_runtime.proto` | The schema (sha256 `9e211660…`, see `protocol.json`) |
|
||||
| `packages/node/native/CMakeLists.txt` | C++ generation + build wiring + ctest |
|
||||
| `packages/node/native/tests/test_shard_protocol_conformance.cpp` | C++ conformance test |
|
||||
| `packages/node/native/testdata/*.binpb` | Committed cross-language vectors |
|
||||
@@ -50,14 +50,19 @@ New:
|
||||
| `scripts/generate_native_protocol.py` | Python generation, with `--check` |
|
||||
| `scripts/generate_protocol_goldens.py` | Vector generation, with `--check` |
|
||||
| `scripts/bootstrap_native_toolchain.sh` | Builds protobuf C++ from source |
|
||||
| `tests/test_native_shard_protocol.py` | 29 Python tests |
|
||||
| `tests/test_native_shard_protocol.py` | 45 Python tests |
|
||||
|
||||
Modified:
|
||||
|
||||
- `packages/node/pyproject.toml` — added `grpcio>=1.60`, `protobuf>=5`; new `proto`
|
||||
extra pinning `grpcio-tools==1.82.1`.
|
||||
- `packages/node/pyproject.toml` — added runtime floors `grpcio>=1.82.1` and
|
||||
`protobuf>=7.35.0`, matching the committed generated-code requirements; new
|
||||
`proto` extra pinning `grpcio-tools==1.82.1`.
|
||||
- `packages/node/meshnet_node/activation_compression.py` — optional bounded zstd
|
||||
output for untrusted protocol frames; existing callers remain compatible.
|
||||
- `packages/node/meshnet_node/native_protocol/__init__.py` — exports negotiated
|
||||
bound constants and whole-session-message validation.
|
||||
|
||||
No other working-tree file was touched. `git status` before this story was clean.
|
||||
The canonical PRD marks only DGR-002 passed. `git status` before this story was clean.
|
||||
|
||||
## 3. Commands and real results
|
||||
|
||||
@@ -76,14 +81,45 @@ ctest --test-dir build/native --output-on-failure -> 1/1 Test #1: shard_prot
|
||||
cmp build/native/cpp_roundtrip.binpb \
|
||||
packages/node/native/testdata/session_request_golden.binpb -> identical (exit 0)
|
||||
|
||||
pytest -q tests/test_native_shard_protocol.py -> 29 passed
|
||||
pytest -q (full suite) -> 712 passed, 12 skipped
|
||||
pytest -q tests/test_native_shard_protocol.py -> 45 passed
|
||||
pytest -q tests/test_native_shard_protocol.py \
|
||||
tests/test_activation_compression.py -> 51 passed
|
||||
pytest -q (final full suite) -> 728 passed, 12 skipped
|
||||
pytest -q tests/test_tracker_routing.py::test_tracker_dashboard_can_cancel_inflight_proxy
|
||||
(after an earlier flaky full-suite failure) -> 1 passed, 1 passed, 1 passed
|
||||
clean minimum-runtime import + codec smoke test -> passed
|
||||
grpcio==1.82.1, protobuf==7.35.0
|
||||
compileall -q packages tests -> OK (exit 0)
|
||||
git diff --check -> clean (exit 0)
|
||||
```
|
||||
|
||||
The C++ lane was rebuilt from scratch (`rm -rf build/native`) using only the
|
||||
documented commands, and reproduced the same result.
|
||||
The C++ lane was rebuilt from scratch by Ralph (`rm -rf build/native`) using only
|
||||
the documented commands, and reproduced the same result. During controller
|
||||
review the user explicitly chose not to repeat the destructive build-directory
|
||||
cleanup, so the independent controller relied on the recorded CMake/CTest run
|
||||
while reproducing every Python/generation/full-suite gate.
|
||||
|
||||
### Controller review corrections
|
||||
|
||||
Independent controller review found and fixed two classes of issue before
|
||||
integration:
|
||||
|
||||
1. Generated stubs required gRPC 1.82.1 and Protobuf 7.35.0, while the initial
|
||||
package metadata allowed much older runtimes that could fail at import time.
|
||||
2. Flow-control bounds were described but not enforced by the reference decoder.
|
||||
Tensor declarations, shape rank/dimensions, fragment/tensor counts, fragments,
|
||||
wire bodies, whole bundles, complete session messages (including envelope
|
||||
overhead), and zstd window/output expansion are now fail-closed against the
|
||||
negotiated/default bounds. Unspecified bundle versions, compression and
|
||||
checksums are rejected rather than interpreted as valid data.
|
||||
3. Negotiated initial credits could exceed `max_inflight_chunks`; credits are now
|
||||
capped by the settled in-flight limit.
|
||||
|
||||
Controller results: protocol tests `45 passed`; protocol plus shared compression
|
||||
tests `51 passed`; final full suite `728 passed, 12 skipped`. A clean environment
|
||||
at the declared minimum gRPC/Protobuf runtime versions imported both generated
|
||||
stub modules and round-tripped the codec. Generation checks, `compileall`, static
|
||||
secret scan, and `git diff --check` all passed.
|
||||
|
||||
### Full-suite note — a pre-existing flaky test
|
||||
|
||||
@@ -104,10 +140,11 @@ pytest -q tests/test_tracker_routing.py::test_tracker_dashboard_can_cancel_infli
|
||||
|
||||
It is a timing race in proxy cancellation (a 3-second in-flight generation raced
|
||||
against the cancel assertion), not a deterministic failure, and it touches no code
|
||||
this story changes. The final full-suite run with DGR-002 applied was green
|
||||
(`712 passed, 12 skipped`) — 683 pre-existing tests plus this story's 29. Flagged
|
||||
for whoever owns the tracker cancel path; **not** fixed here, since silently
|
||||
touching another story's code is out of scope.
|
||||
this story changes. One controller full-suite run reported exactly that one failure
|
||||
(`1 failed, 719 passed, 12 skipped`); three immediate isolated retries all passed
|
||||
in 1.11 seconds, and the final exact-code full suite was green (`728 passed,
|
||||
12 skipped`). It is flagged for whoever owns the tracker cancel path and is **not**
|
||||
fixed here, since silently touching another story's code is out of scope.
|
||||
|
||||
## 4. Acceptance criteria
|
||||
|
||||
@@ -118,12 +155,12 @@ touching another story's code is out of scope.
|
||||
| Bounded chunking for prefill; small decode fast path | `ChunkInfo` + `plan_prefill_chunks` (128-token bound, ADR-0008); `DecodeStep`; `test_prefill_is_split_into_bounded_token_aligned_chunks`, `test_decode_fast_path_is_much_smaller_than_a_full_envelope_chunk` |
|
||||
| Envelope carries schema version, work id, session id, epoch, fingerprint, range/effective start, phase, position, idempotency step, cache expectation, compression, checksum | `Envelope` + `NamedTensor`; `test_envelope_carries_every_field_the_protocol_promises` asserts against the **descriptor**, so deleting a field from the `.proto` fails the test |
|
||||
| Versioned named-tensor bundle: name, shape, dtype, byte order, fragments | `TensorBundle`/`NamedTensor`/`TensorFragment`; `test_named_tensor_bundle_is_versioned_and_fully_described`, `test_bundle_round_trips_multiple_named_tensors` |
|
||||
| Round-trip + compatibility tests in Python and C++ | 29 Python tests; C++ `ctest` 1/1; cross-language byte equality |
|
||||
| Targeted pytest passes | 29 passed |
|
||||
| Round-trip + compatibility tests in Python and C++ | 45 Python tests; C++ `ctest` 1/1; cross-language byte equality |
|
||||
| Targeted pytest passes | 45 passed |
|
||||
| `compileall packages tests` | exit 0 |
|
||||
| `git diff --check` | exit 0 |
|
||||
| Default tests deterministic, download-free, credit-free, GPU-free | Pure in-memory protobuf; no model, no network, no GPU |
|
||||
| Full deterministic pytest passes, or pre-existing failure recorded | 712 passed, 12 skipped; flaky pre-existing test documented above with clean-tree reproduction |
|
||||
| Full deterministic pytest passes, or pre-existing failure recorded | Final exact-code run: 728 passed, 12 skipped; earlier sole flaky failure documented with clean-tree reproduction and 3/3 passing retries |
|
||||
|
||||
## 5. How the cross-language claim is actually earned
|
||||
|
||||
|
||||
@@ -27,3 +27,19 @@ cmp build/native/cpp_roundtrip.binpb packages/node/native/testdata/session_reque
|
||||
# --- repository gates
|
||||
.venv/bin/python -m compileall -q packages tests
|
||||
git diff --check
|
||||
|
||||
# --- independent controller review after Ralph
|
||||
PYTHONPATH=packages/node .venv/bin/python -m pytest -q tests/test_native_shard_protocol.py
|
||||
# -> 45 passed
|
||||
PYTHONPATH=packages/node .venv/bin/python -m pytest -q \
|
||||
tests/test_native_shard_protocol.py tests/test_activation_compression.py
|
||||
# -> 51 passed
|
||||
PYTHONPATH=packages/node .venv/bin/python -m pytest -q
|
||||
# -> final exact-code run: 728 passed, 12 skipped
|
||||
for i in 1 2 3; do PYTHONPATH=packages/node .venv/bin/python -m pytest -q \
|
||||
tests/test_tracker_routing.py::test_tracker_dashboard_can_cancel_inflight_proxy; done
|
||||
# -> 1 passed, 1 passed, 1 passed
|
||||
# clean minimum-runtime venv: protobuf==7.35.0 grpcio==1.82.1
|
||||
# generated pb2 + pb2_grpc imports and one-byte codec round trip -> passed
|
||||
# The user chose to rely on Ralph's recorded successful C++ CMake/CTest run
|
||||
# rather than repeat deletion of an isolated generated build directory.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"schema_version": "SCHEMA_VERSION_1",
|
||||
"bundle_version": 1,
|
||||
"proto_path": "packages/node/native/proto/shard_runtime.proto",
|
||||
"proto_sha256": "077ee34961ab787c67457b1a373f73ec3d577f67086d6bc6a32435f37395b7d6",
|
||||
"proto_sha256": "9e211660b3fcefc88bcdf3851c3571088c00349aacb5adc5ef45083c83d0cce2",
|
||||
"protoc": "grpc_tools 1.82.1 (python) / protobuf 33.1 (C++)",
|
||||
"service": {
|
||||
"GetCapability": {
|
||||
@@ -75,10 +75,21 @@
|
||||
"max_prefill_chunk_tokens": 128,
|
||||
"max_chunk_bytes": 4194304,
|
||||
"max_fragment_bytes": 1048576,
|
||||
"max_inflight_chunks": 8
|
||||
"max_inflight_chunks": 8,
|
||||
"max_fragments_per_tensor": 64,
|
||||
"max_tensors_per_bundle": 64,
|
||||
"max_tensor_rank": 8,
|
||||
"max_tensor_dimension": 2147483647,
|
||||
"whole_session_message_enforced": true
|
||||
},
|
||||
"golden_vectors": {
|
||||
"session_request_golden.binpb": "c2c3df8a717ddeae7bd99624d2c7f34c09a518988de990237fe313b75cff0817",
|
||||
"capability_report_golden.binpb": "71ac5f150775f398515b43a63596a5cbe8d2ad607e7e4de56bd44fbe7987080c"
|
||||
},
|
||||
"verification": {
|
||||
"python_protocol_tests": "45 passed",
|
||||
"python_protocol_and_compression_tests": "51 passed",
|
||||
"full_suite": "728 passed, 12 skipped",
|
||||
"minimum_runtime": "grpcio 1.82.1 / protobuf 7.35.0 passed import and codec smoke"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user