diff --git a/docs/micromate_protocol_reference.md b/docs/micromate_protocol_reference.md index 075108d..2016afb 100644 --- a/docs/micromate_protocol_reference.md +++ b/docs/micromate_protocol_reference.md @@ -1006,9 +1006,17 @@ key there. Writing the offset as a uint32 BE in the same slot is **byte-identica for every offset below 65,536** — so it changes nothing that was verified against THOR's 74 captured frames — and extends the range to 4 GB. -⚠ **Above 64 KB this is inference.** No capture exercises a carry into -`params[1]`. The field's width is established; the device's handling of a -non-zero high byte is not. +✅ **Confirmed on hardware 2026-10-01.** UM20147's 72,560-byte event +(`055d4a83`) downloaded in **71 chunks** at exactly its promised size — chunks +64–70 carry a `0x01` in `params[1]`, and the device served them without +complaint. The field is a uint32; it was inference for one commit. + +🔑 **And it prices a large event over cellular.** 71 chunks × ~0.65 s ≈ **46 +seconds** for one 72 KB histogram, against 0.2 s over USB. That is the +round-trip cost model doing real work: the bytes are nothing, the commands are +everything. A unit holding several events this size is a multi-minute call, and +the untested single-request `offset_hi = 0x10` streaming mode would collapse it +to one round trip — which moves that two-minute bench test up the list. ⚠ **At offset 1 MiB `params[1]` is `0x10`**, which must be escaped on the wire as `10 10`. Unreachable below 64 KB, so the uint32 change is what first makes that diff --git a/micromate/protocol.py b/micromate/protocol.py index 6d8ed49..0c404b1 100644 --- a/micromate/protocol.py +++ b/micromate/protocol.py @@ -182,9 +182,12 @@ def chunk_params(key4: bytes, byte_offset: int) -> bytes: A uint32 here is **byte-identical for every offset below 65,536**, so it changes nothing that was verified against THOR's frames (the replay test - asserts all 74 of them) and extends the range to 4 GB. Above 64 KB it is - **inference**: `params[0:4]` is demonstrably one 4-byte field, because chunk 0 - puts a 4-byte key in it, but no capture exercises a carry into `params[1]`. + asserts all 74 of them) and extends the range to 4 GB. + + ✅ **Confirmed on hardware 2026-10-01.** UM20147's 72,560-byte event + downloaded in **71 chunks** at the exact promised size, which exercises the + carry into `params[1]` on chunks 64–70. It was inference for one commit and + is now evidence. ⚠ This is the **Series III 64 KB page-boundary bug in a new guise** — there, `parse_strt_end_offset()` discards the key's page byte and the `5A` walk diff --git a/tests/test_micromate_protocol.py b/tests/test_micromate_protocol.py index 7335957..00e81c7 100644 --- a/tests/test_micromate_protocol.py +++ b/tests/test_micromate_protocol.py @@ -442,7 +442,12 @@ def test_a_chunk_offset_with_0x10_in_it_is_escaped_on_the_wire(): def test_a_72kb_event_downloads_in_71_chunks(): - """UM20147's event 055d4a83, the one that broke the uint16 assumption.""" + """UM20147's event 055d4a83, the one that broke the uint16 assumption. + + ✅ Confirmed against the real unit 2026-10-01: 71 chunks, exact size, with + chunks 64-70 carrying 0x01 in params[1]. This test pins the arithmetic the + hardware agreed with. + """ size = 72560 n = 71 responses = []