test(perception): record cross-host gRPC recovery and backpressure proof

This commit is contained in:
DCCONSTRUCTIONS
2026-09-02 18:14:51 +03:00
parent 0310592ee3
commit 191612282b
4 changed files with 376 additions and 5 deletions
@@ -1,9 +1,9 @@
# ADR 0049 — Stream-first full perception profiles
Date: 2026-09-01; updated 2026-09-02 16:52 MSK. Status: stage-1 engineering
baseline complete; stage-2 full binary GPU pilot consumes real scoped host facts.
External transport/authentication, native-host GPU inventory, standalone image
and product cutover remain open; local proof is not physical-live acceptance.
Date: 2026-09-01; updated 2026-09-02 18:11 MSK. Status: stage-1 engineering
baseline complete; stage-2 authenticated gRPC candidate has cross-host CPU proof.
Full-graph network integration, native-host GPU inventory, standalone image and
product cutover remain open; transport proof is not physical-live acceptance.
Execution order remains the four stages in
[the ExecPlan](../OBSERVATORY_REALTIME_PROFILES_EXECPLAN.md).
@@ -719,3 +719,61 @@ integration does not constitute the external camera/points binary data plane.
See `experiments/perception/PERCEPTION_STREAM_STAGE1_2026-09-01.md` for measured
component results, bounded validation, Worker maintenance and remaining gates.
Neither this ADR nor passing synthetic contract tests marks the new runtime ready.
## Stage 2 increment 12: external gRPC/TLS candidate (2026-09-02)
`streaming_grpc.py` exposes `/missioncore.perception.v1.BinaryStream/Exchange`.
It is an optional `perception-stream` dependency, locked grpcio1.83.1; it is not
auto-started by the backend or installed into the product LAB path. Both sides
require TLS; the client verifies its supplied trust root and server name. The
local controller alone issues a256-bit random single-use capability with30s
admission expiry, bound to the complete StreamStart and acquisition session.
The endpoint retains only its digest. Invalid/duplicate/stale credentials cannot
reserve a stream, stop its owner, renew a lease, launch a model or create an epoch.
One active stream is admitted; reconnect needs a controller-approved new epoch
and, separately, real decoder/causal-sensor resumption proof. Network disconnect
is not explicit End or Cancel. Production grant delivery is still an integration
gate; the CPU probe transfers ephemeral files only through authenticated SSH.
The generic gRPC method uses identity byte serialization, not generated protobuf
messages. Request messages contain≤64KiB pieces of the unchanged MCI2 wire;
StreamingIngress still validates metadata, fragments, hashes and epoch/source
binding. No archive, duration, file path or executable command is sent. Response
MCR3 is only an envelope over existing domain bytes: magic4, uint64 sequence8,
binding SHA25632, payload SHA25632, then1..1MiB payload. It does not invent a new
scene ontology or claim that full-graph scene/layer serialization is connected.
The actual profile's larger outputs require reviewed fragmentation, not a silent
cap increase. Result age validation and the full result receipt ledger remain
with the graph/application adapter, not the transport envelope.
There are two pending latest replies and one writer/reader per direction; no
background source queue/retry or event-loop callback backlog. Python bridge
storage is reserved inside the existing16MiB mailbox budget. Fixed1MiB HTTP/2
lookahead, disabled BDP growth/retries, bounded metadata/messages/IO are explicit;
native gRPC/TLS/socket memory also needs measured RSS, not a claimed byte-perfect
mapping into mailbox accounting. Public/multi-client DoS hardening is not proved
by this private Worker experiment. A250ms event deadline covers the complete
source event. Even final error-status sending is deadline-bound; otherwise an
unread response can delay cleanup. Late trusted callbacks are quarantined, with
no replacement grant or early byte release until they return. Pending reply
drops are counted; they are not equivalent to end-to-end delivery receipts.
Evidence: initial default64KiB lookahead timed out on1,048,595B. Fixed1MiB passed
two16/16 cross-host samples without changing250ms. Final min/median/max RTT
14.360/23.919/120.815ms on the Mac includes SSH/echo overhead, not clock-subtracted
one-way age.2.202s wait retained the same CPU sentinel PID40 and lease; renewals
32→54. Source clock and resume evidence are explicitly synthetic, model count0.
Peak mailbox6,750,559B; Linux RSS57,244KiB.20 Worker transport tests include1MiB
output, a real slow reader and late-callback cleanup;105 focused Mac tests pass
with the two larger probes intentionally skipped. Final cleanup leaves0bytes,
no temporary listener/container/tunnel/private key/grant. No GPU setters or
durable services changed. Frigate/Ollama remain disabled, Telegraf is Running.
Manifest SHA256 `adf5eaf092feaed6721f66e2adaceded0cdbf55754e1f9953f54623bfb52d331`
at `.runtime/perception-stage2-grpc-20260902T1500Z/manifest.json` (16 artifacts).
Design references: [gRPC flow control](https://grpc.io/docs/guides/flow-control/)
warns that a completed write need not mean network delivery;
[authentication](https://grpc.io/docs/guides/auth/) documents TLS credentials;
[channel options](https://github.com/grpc/grpc/blob/master/include/grpc/impl/channel_arg_names.h)
documents the fixed lookahead window. Source and actual behavior were checked;
these references alone are not a performance qualification.