verify(micromate): 11.0BD confirmed on hardware -- every inference held

UM20147 read over USB by mm_client_check.py.  The Thor firmware line was
entirely inference until now, and two of its three differences were covered
only by SYNTHESISED test frames.  All three held:

- flags = 0x03 identifies the line -> reported firmware_line="thor".  That is
  only reachable if `10 03` in the flags position destuffs before indexing,
  since 0x03 is ETX -- so the escaped-flags case is confirmed too.
- the model string is shorter -> reported "MM/ISEE/S" exactly.  Anchoring the
  search on b"MM/" rather than a fixed span is what made this work.
- the 0x1C block is 4 bytes longer with the extras TRAILING, so from-the-start
  offsets survive -> battery 3.55 V and a clock correct to the second.

That last one is the one that mattered.  Series III's from-the-end offsets
would have given this unit 577.92 V, which is why mm_client_check watches for
an impossible voltage: it is a free self-check on exactly the inference most
likely to be wrong.

Also clean: serial UM20147, 5 setups (factory.MMB -> test2.mmb), active setup
test2.mmb, 15,000,000 B total and free, 21 reads / 2,165 B in.

"One protocol stack drives the whole fleet regardless of firmware line" -- the
headline finding of 2026-09-23 -- is now demonstrated by a working client
rather than by matching response SUBs.

Test and docstring claims downgraded from inference to confirmed where the
hardware settled them, and left as synthesised-frame notes where it did not:
the BEHAVIOUR is confirmed but raw BD bytes are still not in the repo.

Added --capture DIR to mm_client_check: writes a raw_bw_*/raw_s3_* pair in the
layout scratch/mm_frame_parse.py already reads, so a run on an unfamiliar unit
becomes a test fixture without setting up a relay.  Verified by round-tripping
its own output through that parser: 28 frames, 0 bad checksums.

Still not covered: a download from a BD unit (UM20147 had no events stored, so
the chunk walk remains CB-only), raw BD fixture bytes, a monitoring unit, a
nearly-full buffer, and the inbound call-home session.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ru8Lg9HkkYvX9VWWo65SmL
This commit is contained in:
2026-09-30 13:17:53 -04:00
co-authored by Claude Opus 5
parent 0d6eb1621f
commit b55e4e946a
5 changed files with 84 additions and 13 deletions
+4 -3
View File
@@ -208,9 +208,10 @@ class MicromateClient:
battery voltage of 577.92 V. The four extra bytes are trailing, so
from-the-start offsets hold for both lines.
⚠ Verified on `11.0CB` only. That the same offsets hold on `11.0BD`
follows from the extra bytes being trailing, which is documented but not
something this code has seen.
✅ **Confirmed on `11.0BD` 2026-09-30.** UM20147 read back 3.55 V and
a clock correct to the second over USB, so the from-the-start offsets do
survive the four extra trailing bytes. Had they not, the battery would
have read 577.92 V — which is what makes this cheap to check.
"""
data = self._proto.read_monitor_status()
c = _content(data)