test(adr-110): cross-language wire-format conformance gate

Iter 21 — ultra-opt for protocol correctness across the two production
decoders. Pin the same 32-byte canonical hex in both Python and Rust
tests; if either decoder drifts from the wire, ONE of the tests starts
failing — and it's clear which side moved.

Canonical packet: COM9 sync-pkt #1 from §A0.12 live capture, expressed
as exact little-endian bytes:

  10a111c5 09 01 06 00                      magic + node + ver + flags + rsvd
  f26db70100000000                          local_us = 28_798_450
  c5aca50100000000                          epoch_us = 27_634_885
  1400000000000000                          sequence = 20 + reserved

Python test:
  archive/v1/tests/unit/test_esp32_binary_parser.py::TestSyncPacketParser
  ::test_canonical_wire_bytes_match_rust_decoder
  — decodes the pinned hex, asserts every field including the §A0.10
    1,163,565 µs offset.

Rust test:
  v2/crates/wifi-densepose-hardware/src/sync_packet.rs::tests
  ::canonical_wire_bytes_match_python_decoder
  — decodes the same bytes, asserts the same fields, then re-encodes
    via to_bytes() and asserts the round-trip produces the EXACT same
    32 bytes. So this also catches drift in the Rust encoder.

Test counts after this iter:
  Rust sync_packet: 15/15 green (was 14)
  Python SyncPacketParser: 7/7 green (was 6)

Branch contract: if a future PR changes the firmware wire format, BOTH
tests must be updated atomically with the new canonical hex. CI will
gate this naturally.

Co-Authored-By: claude-flow <ruv@ruv.net>
This commit is contained in:
ruv 2026-05-23 13:52:44 -04:00
parent 40bd6b81b8
commit 82be960de5
2 changed files with 75 additions and 0 deletions

View File

@ -364,3 +364,35 @@ class TestSyncPacketParser:
assert csi_magic == ESP32BinaryParser.MAGIC
assert sync_magic == SyncPacketParser.MAGIC
assert csi_magic != sync_magic
def test_canonical_wire_bytes_match_rust_decoder(self):
"""ADR-110 iter 21 — cross-language wire-format conformance gate.
These exact bytes also appear pinned in the Rust hardware crate's
`canonical_wire_bytes_match_python_decoder` test (same field
values, encoded by Rust's `SyncPacket::to_bytes`). If Python's
hardcoded hex stops matching what Rust produces from the equivalent
SyncPacket struct, ONE of the decoders has drifted from the wire.
Canonical packet: COM9 sync-pkt #1 from §A0.12 live capture.
"""
canonical = bytes.fromhex(
"10a111c509010600" # magic LE + node=9 + ver=1 + flags=0x06 + reserved
"f26db70100000000" # local_us = 28_798_450 (LE u64)
"c5aca50100000000" # epoch_us = 27_634_885 (LE u64)
"1400000000000000" # sequence = 20 (LE u32) + 4 reserved bytes
)
assert len(canonical) == SyncPacketParser.SIZE == 32
pkt = SyncPacketParser.parse(canonical)
assert pkt.node_id == 9
assert pkt.proto_ver == 1
assert pkt.flags_raw == 0x06
assert pkt.is_leader is False
assert pkt.is_valid is True
assert pkt.smoothed_used is True
assert pkt.local_us == 28_798_450
assert pkt.epoch_us == 27_634_885
assert pkt.sequence == 20
# Recovered offset matches §A0.10's measured 1.16-second boot delta.
assert pkt.local_us - pkt.epoch_us == 1_163_565

View File

@ -425,4 +425,47 @@ mod tests {
assert_eq!(pkt.to_bytes().len(), SYNC_PACKET_SIZE);
assert_eq!(SYNC_PACKET_SIZE, 32);
}
/// ADR-110 iter 21 — cross-language wire-format conformance gate.
///
/// These exact bytes are ALSO pinned in the Python test
/// `test_canonical_wire_bytes_match_rust_decoder` in
/// `archive/v1/tests/unit/test_esp32_binary_parser.py`. If this
/// canonical hex stops matching what Python emits for the same
/// SyncPacket fields, ONE of the decoders has drifted from the wire.
///
/// Canonical packet: COM9 sync-pkt #1 from §A0.12 live capture.
#[test]
fn canonical_wire_bytes_match_python_decoder() {
// Exact bytes matching the Python pin (hex-decoded by hand to bytes).
let canonical: [u8; 32] = [
0x10, 0xa1, 0x11, 0xc5, // magic 0xC511A110 (LE u32)
0x09, // node_id = 9
0x01, // proto_ver = 1
0x06, // flags: bit1=is_valid, bit2=smoothed_used
0x00, // reserved
0xf2, 0x6d, 0xb7, 0x01, 0x00, 0x00, 0x00, 0x00, // local_us = 28_798_450
0xc5, 0xac, 0xa5, 0x01, 0x00, 0x00, 0x00, 0x00, // epoch_us = 27_634_885
0x14, 0x00, 0x00, 0x00, // sequence = 20
0x00, 0x00, 0x00, 0x00, // reserved
];
let decoded = SyncPacket::from_bytes(&canonical).unwrap();
assert_eq!(decoded.node_id, 9);
assert_eq!(decoded.proto_ver, 1);
assert_eq!(decoded.flags.to_byte(), 0x06);
assert!(!decoded.flags.is_leader);
assert!(decoded.flags.is_valid);
assert!(decoded.flags.smoothed_used);
assert_eq!(decoded.local_us, 28_798_450);
assert_eq!(decoded.epoch_us, 27_634_885);
assert_eq!(decoded.sequence, 20);
// §A0.10's measured 1.16-second boot delta.
assert_eq!(decoded.local_minus_epoch_us(), 1_163_565);
// Round-trip: re-encoding the decoded struct must produce the same
// canonical bytes — this is what catches any drift in to_bytes.
let re_encoded = decoded.to_bytes();
assert_eq!(re_encoded, canonical,
"Rust to_bytes drifted from the canonical pin — Python decoder will break");
}
}