motorcortex-rust 0.5.0

Motorcortex Rust: a Rust client for the Motorcortex Core real-time control system (async + blocking).
Documentation
# TODO

Forward-looking work. For the async-first rewrite that shipped in
0.5.0, see [`CHANGELOG.md`](CHANGELOG.md) and the git log.

## Next release (0.5.x / 0.6.0)

- **Per-RPC performance bench — rust vs. python.** Run the same
  16-clone stress shape against each of `get_parameter`,
  `set_parameter`, `get_parameters` (batch), `set_parameters`
  (batch). Measure **throughput** (RPCs/sec across all clones)
  and **per-call wall-clock** (min / avg / p99 / max). Add sibling
  `#[ignore]`d tests next to
  `tests/integration/async_stress.rs::stress_16_clones_hot_get_parameter`;
  print the summary via `eprintln!`. Then run the same shape against
  the python client (`motorcortex-python/motorcortex/request.py`)
  hitting the same vendored `test_server` on the same machine, and
  publish a side-by-side table (rust / python, one row per RPC) in
  `bench/README.md`. Goal: performance parity at minimum — the
  rust driver should match or beat python on every RPC. Record host
  CPU model + server build hash with each run.

- **Cap-exceeded integration test for `max_reconnect_attempts`.**
  Needs a server-side `MCX_TEST_FRESH_SESSIONS=1` flag so the
  replacement `test_server` rejects restored tokens. The pure
  state-machine already has full unit coverage in
  `core::driver::state_machine_tests`; this would be the
  end-to-end belt.

- **Dependency bumps.** When a refresh cycle is convenient:
  - `prost` / `prost-build` 0.13 → 0.14 (minor, touches the
    `.proto` pipeline).
  - `ctor` 0.4 → 0.10 (test-only, big version jump).

## Deferred (explicitly not planned for the current design)

- **`nng_aio`-based true-async driver.** Motorcortex workloads are
  bounded (kHz telemetry, a handful of concurrent RPCs). The
  dedicated-`std::thread` driver is honest and fast enough. Keep
  `tokio::runtime::Builder::max_blocking_threads(N)` on the order
  of 4 if callers build their own runtime; don't chase purity we
  don't need.

- **`Session` struct.** Revisit only if three+ consumers end up
  duplicating the `connect → login → request_parameter_tree`
  preamble. Until then the `connect_to` / `parse_url` helpers are
  enough.

- **`tracing` migration.** Optional quality-of-life. The NNG side
  already logs via `nng_log_*`; adding `tracing` spans on top is
  a nice-to-have, not a gap.

## Outstanding low-priority findings

- **`parameter_value/{get,set}_parameter_value.rs`**~1700 lines
  of per-type trait impls with many no-op methods (e.g. `&str::to_bytes_as_i32``vec![]`).
  Worth refactoring to a single `Codec<T>` trait with ~12 dispatch
  arms (~200 lines). Not a correctness issue, just tech debt.

- **`blocking/request.rs` + `blocking/subscription.rs` coverage.**
  Currently 95 % / 100 % after the 0.5.0 polish pass; if the
  blocking façade grows, keep the target at ≥80 %.