Commit Graph

4 Commits

Author SHA1 Message Date
ruv 82be960de5 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>
2026-05-23 13:52:44 -04:00
ruv 3a6648c290 test+docs(adr-110): 6 SyncPacketParser tests + README/user-guide for v0.7.0
Iter 13 — solidifies v0.7.0 as a real, reviewable release.

Tests (archive/v1/tests/unit/test_esp32_binary_parser.py):
- TestSyncPacketParser (6 tests, all passing in 0.27s):
  * test_follower_typical_packet_roundtrips — matches the COM9-witnessed
    sync-pkt #1 byte-for-byte, including the 1,163,565 µs offset that
    §A0.10 measured for the COM9-vs-COM12 boot-time delta
  * test_leader_packet_has_local_close_to_epoch — COM12 leader case,
    flags=0x03, epoch ≈ local
  * test_magic_mismatch_raises — non-sync datagrams don't silently decode
  * test_short_packet_raises — early error vs silent truncation
  * test_all_flag_combinations — every (leader, valid, smoothed) triple
    round-trips independently
  * test_dispatch_distinguishes_csi_from_sync — CSI vs sync magics differ
    so a host can dispatch by leading u32

Docs:
- README C6 hardware row now headlines v0.7.0 (was v0.6.7), names the
  measured 99.56% match / 104 µs stdev / 3.95× suppression numbers, and
  acknowledges the firmware-side ADR-110 substrate closure.
- docs/user-guide.md firmware release table now lists v0.7.0 / v0.6.9 /
  v0.6.8 / v0.6.7 chain with one-liner highlights so 4MB-flash users +
  multistatic operators know which release brings what.

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-05-23 13:00:42 -04:00
ruv 8eaa92cf21 feat(python): host-side decode for ADR-018 byte 18-19 (ADR-110)
Python ESP32BinaryParser was using struct format '<IBBHIIBB2x' — the
'2x' skipped bytes 18-19 as reserved. After the Rust-side decoder was
extended to surface PPDU type + flags, the Python pipeline (which
archive/v1 still uses for testing + the proof verifier) needs the same
update so its consumers see the HE metadata too.

csi_extractor.py:
- HEADER_FMT now '<IBBHIIBBBB' (captures bytes 18-19)
- New metadata fields: ppdu_type ('ht_legacy'|'he_su'|'he_mu'|'he_tb'|'unknown'),
  ppdu_type_raw, he_capable, bw40, stbc, ldpc, ieee802154_sync_valid,
  adr018_flags_raw
- Class constants PPDU_HT_LEGACY..PPDU_UNKNOWN mirror the firmware

test_esp32_binary_parser.py:
- build_binary_frame() takes optional ppdu_byte + flags_byte (default 0)
- New TestAdr110ByteEncoding class with 5 tests:
  - Pre-ADR-110 zeros decode as 'ht_legacy' + all-flags-false
  - HE-SU / HE-MU / HE-TB decode correctly
  - 0xFF decodes as 'unknown'
  - All-flags-set round-trip (0x1D)

11/11 parser tests pass (6 existing + 5 new). Backwards compat verified.

Pairs with the Rust-side decoder in commit 3959fabf3. Both pipelines now
read the same wire format produced by the C6 firmware's
CONFIG_CSI_FRAME_HE_TAGGING path.

Ref: ruvnet/RuView#762, draft PR #764

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-05-22 22:46:37 -04:00
rUv 81cc241b9e
chore(repo): move v1/ → archive/v1/ + add archive/README.md (#430)
The Rust port at v2/ has been the primary codebase since the rename
in #427. The Python implementation at v1/ is no longer the active
target; the only load-bearing path is the deterministic proof bundle
at v1/data/proof/ (per ADR-011 / ADR-028 witness verification).

Move the whole Python tree into archive/v1/ and document the policy
in archive/README.md: no new features, bug fixes only when they affect
a still-load-bearing path (currently just the proof), CI continues to
verify the proof on every push and PR.

Path references updated in 26 files via path-pattern sed (only
matches v1/<known-child> patterns, never bare v1 or API URLs like
/api/v1/). Two double-prefix typos (archive/archive/v1/) caught and
hand-fixed in verify-pipeline.yml and ADR-011.

Validated:
- Python proof verify.py imports cleanly at archive/v1/data/proof/
  (numpy/scipy still required; CI installs requirements-lock.txt
  from archive/v1/ now)
- cargo test --workspace --no-default-features → 1,539 passed,
  0 failed, 8 ignored (unaffected by Python tree relocation)
- ESP32-S3 on COM7 untouched (no firmware paths changed)

After-merge: contributors should re-run any local `python v1/...`
commands as `python archive/v1/...` (CLAUDE.md and CHANGELOG already
updated).
2026-04-25 23:07:52 -04:00